mirror of
https://github.com/virt-manager/virt-manager.git
synced 2024-12-22 13:34:07 +03:00
viewers: Enable window modifiers when viewer doesn't have keyboard
Right now this is tied to widget focus, which is too strong. This changes it so that say clicking on the window title or toolbar then allows the user to use Alt+F to trigger the File menu for example. This roughly matches how virt-viewer works https://bugzilla.redhat.com/show_bug.cgi?id=1824480 Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
parent
33a61f7f30
commit
aafb874c85
@ -53,6 +53,15 @@ class Console(uiutils.UITestCase):
|
||||
conn = None
|
||||
extraopts = None
|
||||
|
||||
def _destroy(self, win):
|
||||
smenu = win.find("Menu", "toggle button")
|
||||
smenu.click()
|
||||
smenu.find("Force Off", "menu item").click()
|
||||
self._click_alert_button("you sure", "Yes")
|
||||
run = win.find("Run", "push button")
|
||||
uiutils.check(lambda: run.sensitive)
|
||||
|
||||
|
||||
##############
|
||||
# Test cases #
|
||||
##############
|
||||
@ -134,8 +143,17 @@ class Console(uiutils.UITestCase):
|
||||
scalemenu.point()
|
||||
scalemenu.find("Only", "radio menu item").click()
|
||||
|
||||
# Check that modifiers don't work
|
||||
win.click()
|
||||
self.sleep(1)
|
||||
win.keyCombo("<ctrl>w")
|
||||
uiutils.check(lambda: win.showing)
|
||||
dom.destroy()
|
||||
win.find("Guest is not running.")
|
||||
win.click_title()
|
||||
self.sleep(1)
|
||||
win.keyCombo("<ctrl>w")
|
||||
uiutils.check(lambda: not win.showing)
|
||||
|
||||
@_vm_wrapper("uitests-vnc-standard")
|
||||
def testConsoleVNCStandard(self, dom):
|
||||
@ -172,10 +190,7 @@ class Console(uiutils.UITestCase):
|
||||
uiutils.check(lambda: con.showing)
|
||||
|
||||
# Restart VM to retrigger console connect
|
||||
smenu = win.find("Menu", "toggle button")
|
||||
smenu.click()
|
||||
smenu.find("Force Off", "menu item").click()
|
||||
self._click_alert_button("you sure", "Yes")
|
||||
self._destroy(win)
|
||||
win.find("Run", "push button").click()
|
||||
uiutils.check(lambda: passwd.showing)
|
||||
# Password should be filled in
|
||||
@ -186,10 +201,7 @@ class Console(uiutils.UITestCase):
|
||||
uiutils.check(lambda: con.showing)
|
||||
|
||||
# Restart VM to retrigger console connect
|
||||
smenu = win.find("Menu", "toggle button")
|
||||
smenu.click()
|
||||
smenu.find("Force Off", "menu item").click()
|
||||
self._click_alert_button("you sure", "Yes")
|
||||
self._destroy(win)
|
||||
win.find("Run", "push button").click()
|
||||
uiutils.check(lambda: passwd.showing)
|
||||
# Password should be empty now
|
||||
@ -267,10 +279,7 @@ class Console(uiutils.UITestCase):
|
||||
|
||||
win.find("Details", "radio button").click()
|
||||
win.find("Console", "radio button").click()
|
||||
smenu = win.find("Menu", "toggle button")
|
||||
smenu.click()
|
||||
smenu.find("Force Off", "menu item").click()
|
||||
self._click_alert_button("you sure", "Yes")
|
||||
self._destroy(win)
|
||||
view = self.app.root.find("^View$", "menu")
|
||||
view.click()
|
||||
# Triggers some tooltip cases
|
||||
@ -286,6 +295,18 @@ class Console(uiutils.UITestCase):
|
||||
term = win.find("Serial Terminal")
|
||||
uiutils.check(lambda: term.showing)
|
||||
|
||||
# Ensure ctrl+w doesn't close the window, modifiers are disabled
|
||||
term.click()
|
||||
win.keyCombo("<ctrl>w")
|
||||
uiutils.check(lambda: win.showing)
|
||||
# Shut it down, ensure <ctrl>w works again
|
||||
self._destroy(win)
|
||||
win.click_title()
|
||||
self.sleep(1)
|
||||
win.keyCombo("<ctrl>w")
|
||||
uiutils.check(lambda: not win.showing)
|
||||
|
||||
|
||||
@_vm_wrapper("uitests-spice-specific",
|
||||
opts=["--test-options=spice-agent",
|
||||
"--test-options=fake-console-resolution"])
|
||||
|
@ -396,16 +396,6 @@ class vmmConsolePages(vmmGObjectUI):
|
||||
|
||||
self.topwin.set_title(title)
|
||||
|
||||
def _someone_has_focus(self):
|
||||
if (self._viewer and
|
||||
self._viewer.console_has_focus() and
|
||||
self._viewer.console_is_open()):
|
||||
return True
|
||||
|
||||
for serial in self._serial_consoles:
|
||||
if serial.has_focus():
|
||||
return True
|
||||
|
||||
def _disable_modifiers(self):
|
||||
if self._gtk_settings_accel is not None:
|
||||
return
|
||||
@ -876,8 +866,18 @@ class vmmConsolePages(vmmGObjectUI):
|
||||
def _viewer_allocate_cb(self, src, ignore):
|
||||
self.widget("console-gfx-scroll").queue_resize()
|
||||
|
||||
def _viewer_focus_changed(self, ignore1=None, ignore2=None):
|
||||
if self._someone_has_focus():
|
||||
def _viewer_keyboard_grab_cb(self, src):
|
||||
self._viewer_sync_modifiers()
|
||||
|
||||
def _serial_focus_changed_cb(self, src, event):
|
||||
self._viewer_sync_modifiers()
|
||||
|
||||
def _viewer_sync_modifiers(self):
|
||||
serial_has_focus = any([s.has_focus() for s in self._serial_consoles])
|
||||
viewer_keyboard_grab = (self._viewer and
|
||||
self._viewer.console_has_keyboard_grab())
|
||||
|
||||
if serial_has_focus or viewer_keyboard_grab:
|
||||
self._disable_modifiers()
|
||||
else:
|
||||
self._enable_modifiers()
|
||||
@ -926,7 +926,7 @@ class vmmConsolePages(vmmGObjectUI):
|
||||
log.debug("Viewer disconnected")
|
||||
|
||||
# Make sure modifiers are set correctly
|
||||
self._viewer_focus_changed()
|
||||
self._viewer_sync_modifiers()
|
||||
|
||||
self._viewer_disconnected_set_page(errdetails, ssherr)
|
||||
self._refresh_resizeguest_from_settings()
|
||||
@ -936,15 +936,15 @@ class vmmConsolePages(vmmGObjectUI):
|
||||
self._activate_viewer_page()
|
||||
|
||||
# Make sure modifiers are set correctly
|
||||
self._viewer_focus_changed()
|
||||
self._viewer_sync_modifiers()
|
||||
|
||||
def _connect_viewer_signals(self):
|
||||
self._viewer.connect("add-display-widget", self._viewer_add_display)
|
||||
self._viewer.connect("pointer-grab", self._pointer_grabbed)
|
||||
self._viewer.connect("pointer-ungrab", self._pointer_ungrabbed)
|
||||
self._viewer.connect("size-allocate", self._viewer_allocate_cb)
|
||||
self._viewer.connect("focus-in-event", self._viewer_focus_changed)
|
||||
self._viewer.connect("focus-out-event", self._viewer_focus_changed)
|
||||
self._viewer.connect("keyboard-grab", self._viewer_keyboard_grab_cb)
|
||||
self._viewer.connect("keyboard-ungrab", self._viewer_keyboard_grab_cb)
|
||||
self._viewer.connect("connected", self._viewer_connected)
|
||||
self._viewer.connect("disconnected", self._viewer_disconnected)
|
||||
self._viewer.connect("auth-error", self._viewer_auth_error)
|
||||
@ -985,8 +985,8 @@ class vmmConsolePages(vmmGObjectUI):
|
||||
|
||||
if not serial:
|
||||
serial = vmmSerialConsole(self.vm, target_port, name)
|
||||
serial.set_focus_callbacks(self._viewer_focus_changed,
|
||||
self._viewer_focus_changed)
|
||||
serial.set_focus_callbacks(self._serial_focus_changed_cb,
|
||||
self._serial_focus_changed_cb)
|
||||
|
||||
title = Gtk.Label(label=name)
|
||||
self.widget("serial-pages").append_page(serial.get_box(), title)
|
||||
|
@ -36,10 +36,10 @@ class Viewer(vmmGObject):
|
||||
__gsignals__ = {
|
||||
"add-display-widget": (vmmGObject.RUN_FIRST, None, [object]),
|
||||
"size-allocate": (vmmGObject.RUN_FIRST, None, [object]),
|
||||
"focus-in-event": (vmmGObject.RUN_FIRST, None, [object]),
|
||||
"focus-out-event": (vmmGObject.RUN_FIRST, None, [object]),
|
||||
"pointer-grab": (vmmGObject.RUN_FIRST, None, []),
|
||||
"pointer-ungrab": (vmmGObject.RUN_FIRST, None, []),
|
||||
"keyboard-grab": (vmmGObject.RUN_FIRST, None, []),
|
||||
"keyboard-ungrab": (vmmGObject.RUN_FIRST, None, []),
|
||||
"connected": (vmmGObject.RUN_FIRST, None, []),
|
||||
"disconnected": (vmmGObject.RUN_FIRST, None, [str, str]),
|
||||
"auth-error": (vmmGObject.RUN_FIRST, None, [str, bool]),
|
||||
@ -54,6 +54,7 @@ class Viewer(vmmGObject):
|
||||
self._vm = vm
|
||||
self._ginfo = ginfo
|
||||
self._tunnels = SSHTunnels(self._ginfo)
|
||||
self._keyboard_grab = False
|
||||
|
||||
self.add_gsettings_handle(
|
||||
self.config.on_keys_combination_changed(self._refresh_grab_keys))
|
||||
@ -90,10 +91,6 @@ class Viewer(vmmGObject):
|
||||
|
||||
self._display.connect("size-allocate",
|
||||
self._make_signal_proxy("size-allocate"))
|
||||
self._display.connect("focus-in-event",
|
||||
self._make_signal_proxy("focus-in-event"))
|
||||
self._display.connect("focus-out-event",
|
||||
self._make_signal_proxy("focus-out-event"))
|
||||
|
||||
|
||||
|
||||
@ -210,6 +207,8 @@ class Viewer(vmmGObject):
|
||||
return self._grab_focus()
|
||||
def console_has_focus(self):
|
||||
return self._has_focus()
|
||||
def console_has_keyboard_grab(self):
|
||||
return bool(self._display and self._keyboard_grab)
|
||||
def console_set_size_request(self, *args, **kwargs):
|
||||
return self._set_size_request(*args, **kwargs)
|
||||
def console_size_allocate(self, *args, **kwargs):
|
||||
@ -297,6 +296,8 @@ class VNCViewer(Viewer):
|
||||
self._make_signal_proxy("pointer-grab"))
|
||||
self._display.connect("vnc-pointer-ungrab",
|
||||
self._make_signal_proxy("pointer-ungrab"))
|
||||
self._display.connect("vnc-keyboard-grab", self._keyboard_grab_cb)
|
||||
self._display.connect("vnc-keyboard-ungrab", self._keyboard_ungrab_cb)
|
||||
|
||||
self._display.connect("vnc-auth-credential", self._auth_credential)
|
||||
self._display.connect("vnc-auth-failure", self._auth_failure_cb)
|
||||
@ -306,6 +307,14 @@ class VNCViewer(Viewer):
|
||||
|
||||
self._display.show()
|
||||
|
||||
def _keyboard_grab_cb(self, src):
|
||||
self._keyboard_grab = True
|
||||
self.emit("keyboard-grab")
|
||||
|
||||
def _keyboard_ungrab_cb(self, src):
|
||||
self._keyboard_grab = False
|
||||
self.emit("keyboard-ungrab")
|
||||
|
||||
def _connected_cb(self, ignore):
|
||||
self._tunnels.unlock()
|
||||
self.emit("connected")
|
||||
@ -485,20 +494,28 @@ class SpiceViewer(Viewer):
|
||||
# Private helpers #
|
||||
###################
|
||||
|
||||
def _init_widget(self):
|
||||
self.emit("add-display-widget", self._display)
|
||||
self._display.realize()
|
||||
|
||||
self._display.connect("mouse-grab", self._mouse_grab_event)
|
||||
|
||||
self._display.show()
|
||||
|
||||
def _mouse_grab_event(self, ignore, grab):
|
||||
def _mouse_grab_cb(self, src, grab):
|
||||
if grab:
|
||||
self.emit("pointer-grab")
|
||||
else:
|
||||
self.emit("pointer-ungrab")
|
||||
|
||||
def _keyboard_grab_cb(self, src, grab):
|
||||
self._keyboard_grab = grab
|
||||
if grab:
|
||||
self.emit("keyboard-grab")
|
||||
else:
|
||||
self.emit("keyboard-ungrab")
|
||||
|
||||
def _init_widget(self):
|
||||
self.emit("add-display-widget", self._display)
|
||||
self._display.realize()
|
||||
|
||||
self._display.connect("mouse-grab", self._mouse_grab_cb)
|
||||
self._display.connect("keyboard-grab", self._keyboard_grab_cb)
|
||||
|
||||
self._display.show()
|
||||
|
||||
def _create_spice_session(self):
|
||||
self._spice_session = SpiceClientGLib.Session()
|
||||
SpiceClientGLib.set_session_option(self._spice_session)
|
||||
|
Loading…
Reference in New Issue
Block a user