From 9e312c7a67ed20d764cea3e30128860889eec0a4 Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Thu, 2 Dec 2010 13:41:22 -0500 Subject: [PATCH] console: Rework keygrab/accelerator preferences Reduce the keygrab options to a single question: whether to enable the console window menu modifiers while the VNC console is active. This makes the VNC widget focus act like a regular app (rather than default to stealing keyboard focus on mouse over), and is the most intuitive I think we can get. Inspired by vinagre. --- src/virt-manager.schemas.in | 12 +++--- src/virtManager/config.py | 15 +++---- src/virtManager/console.py | 53 +++++++++++++------------ src/virtManager/preferences.py | 20 +++++----- src/vmm-preferences.glade | 71 +++++++++++++++++++--------------- 5 files changed, 93 insertions(+), 78 deletions(-) diff --git a/src/virt-manager.schemas.in b/src/virt-manager.schemas.in index 3a94bf37e..2aeeb4773 100644 --- a/src/virt-manager.schemas.in +++ b/src/virt-manager.schemas.in @@ -118,15 +118,15 @@ - /schemas/apps/::PACKAGE::/console/keygrab - /apps/::PACKAGE::/console/keygrab + /schemas/apps/::PACKAGE::/console/enable-accels + /apps/::PACKAGE::/console/enable-accels ::PACKAGE:: - int - 2 + bool + false - When to grab keyboard input for the console - Whether to grab keyboard input for a guest console. 0 = never, 1 = only when in full screen mode, 2 = when mouse is over console + Enable menu accelerators in console window + Whether to enable menu accelerators while connected to the guest graphical console. diff --git a/src/virtManager/config.py b/src/virtManager/config.py index b54735559..ea0fd026e 100644 --- a/src/virtManager/config.py +++ b/src/virtManager/config.py @@ -425,15 +425,16 @@ class vmmConfig: def set_console_popup(self, pref): self.conf.set_int(self.conf_dir + "/console/popup", pref) - def on_console_keygrab_changed(self, callback): - self.conf.notify_add(self.conf_dir + "/console/keygrab", callback) - def get_console_keygrab(self): - console_pref = self.conf.get_int(self.conf_dir + "/console/keygrab") + def on_console_accels_changed(self, callback): + self.conf.notify_add(self.conf_dir + "/console/enable-accels", callback) + def get_console_accels(self): + console_pref = self.conf.get_bool(self.conf_dir + + "/console/enable-accels") if console_pref == None: - console_pref = 0 + console_pref = False return console_pref - def set_console_keygrab(self, pref): - self.conf.set_int(self.conf_dir + "/console/keygrab", pref) + def set_console_accels(self, pref): + self.conf.set_bool(self.conf_dir + "/console/enable-accels", pref) def on_console_scaling_changed(self, callback): self.conf.notify_add(self.conf_dir + "/console/scaling", callback) diff --git a/src/virtManager/console.py b/src/virtManager/console.py index 1028d123c..ea7773b75 100644 --- a/src/virtManager/console.py +++ b/src/virtManager/console.py @@ -75,6 +75,7 @@ class vmmConsolePages(gobject.GObject): self.vncViewerRetriesScheduled = 0 self.vncViewerRetryDelay = 125 self.vnc_connected = False + self.modifiers_enabled = True self.vncViewer = gtkvnc.Display() self.window.get_widget("console-vnc-viewport").add(self.vncViewer) @@ -129,10 +130,12 @@ class vmmConsolePages(gobject.GObject): self.vm.on_console_scaling_changed(self.refresh_scaling) self.refresh_scaling() - self.set_keyboard_grab() - self.config.on_console_keygrab_changed(self.set_keyboard_grab) + self.vncViewer.set_keyboard_grab(False) self.vncViewer.set_pointer_grab(True) + self.set_enable_accel() + self.config.on_console_accels_changed(self.set_enable_accel) + scroll = self.window.get_widget("console-vnc-scroll") scroll.connect("size-allocate", self.scroll_size_allocate) @@ -141,19 +144,25 @@ class vmmConsolePages(gobject.GObject): self.vncViewer.connect("vnc-auth-credential", self._vnc_auth_credential) self.vncViewer.connect("vnc-initialized", self._vnc_initialized) self.vncViewer.connect("vnc-disconnected", self._vnc_disconnected) - self.vncViewer.connect("vnc-keyboard-grab", self.keyboard_grabbed) - self.vncViewer.connect("vnc-keyboard-ungrab", self.keyboard_ungrabbed) self.vncViewer.connect("vnc-desktop-resize", self.desktop_resize) + self.vncViewer.connect("focus-in-event", self._vnc_focus_changed) + self.vncViewer.connect("focus-out-event", self._vnc_focus_changed) self.vncViewer.show() ############# # Listeners # ############# - def keyboard_grabbed(self, src): - self._disable_modifiers() - def keyboard_ungrabbed(self, src=None): - self._enable_modifiers() + def _vnc_focus_changed(self, ignore1=None, ignore2=None): + has_focus = self.vncViewer.get_property("has-focus") + force_accel = self.config.get_console_accels() + + if force_accel: + self._enable_modifiers() + elif has_focus and self.vnc_connected: + self._disable_modifiers() + else: + self._enable_modifiers() def pointer_grabbed(self, src): keystr = None @@ -191,10 +200,10 @@ class vmmConsolePages(gobject.GObject): settings.set_property('gtk-menu-bar-accel', None) if has_property(settings, "gtk-enable-mnemonics"): - self.gtk_settings_mnemonic = settings.get_property("gtk-enable-mnemonics") + self.gtk_settings_mnemonic = settings.get_property( + "gtk-enable-mnemonics") settings.set_property("gtk-enable-mnemonics", False) - def _enable_modifiers(self): if self.gtk_settings_accel is None: return @@ -210,10 +219,10 @@ class vmmConsolePages(gobject.GObject): for g in self.accel_groups: self.topwin.add_accel_group(g) - def set_keyboard_grab(self, ignore=None, ignore1=None, - ignore2=None, ignore3=None): - grab = self.config.get_console_keygrab() == 2 - self.vncViewer.set_keyboard_grab(grab) + def set_enable_accel(self, ignore=None, ignore1=None, + ignore2=None, ignore3=None): + # Make sure modifiers are up to date + self._vnc_focus_changed() def refresh_scaling(self, ignore1=None, ignore2=None, ignore3=None, ignore4=None): @@ -270,17 +279,8 @@ class vmmConsolePages(gobject.GObject): if do_fullscreen: self.topwin.fullscreen() - - if self.config.get_console_keygrab() == 1: - gtk.gdk.keyboard_grab(self.vncViewer.window, False, 0L) - self._disable_modifiers() - self.window.get_widget("toolbar-box").hide() else: - if self.config.get_console_keygrab() == 1: - self._enable_modifiers() - gtk.gdk.keyboard_ungrab(0L) - self.topwin.unfullscreen() if self.window.get_widget("details-menu-view-toolbar").get_active(): @@ -433,7 +433,9 @@ class vmmConsolePages(gobject.GObject): self.vnc_connected = False logging.debug("VNC disconnected") - self.keyboard_ungrabbed() + + # Make sure modifiers are set correctly + self._vnc_focus_changed() if (self.skip_connect_attempt() or self.guest_not_avail()): @@ -458,6 +460,9 @@ class vmmConsolePages(gobject.GObject): self.vncViewerRetriesScheduled = 0 self.vncViewerRetryDelay = 125 + # Make sure modifiers are set correctly + self._vnc_focus_changed() + def schedule_retry(self): if self.vncViewerRetriesScheduled >= 10: logging.error("Too many connection failures, not retrying again") diff --git a/src/virtManager/preferences.py b/src/virtManager/preferences.py index 26ef8c4c4..da37d39ca 100644 --- a/src/virtManager/preferences.py +++ b/src/virtManager/preferences.py @@ -33,14 +33,16 @@ class vmmPreferences(gobject.GObject): } def __init__(self, config): gobject.GObject.__init__(self) - self.window = gtk.glade.XML(config.get_glade_dir() + "/vmm-preferences.glade", "vmm-preferences", domain="virt-manager") + self.window = gtk.glade.XML( + config.get_glade_dir() + "/vmm-preferences.glade", + "vmm-preferences", domain="virt-manager") self.config = config self.topwin = self.window.get_widget("vmm-preferences") self.config.on_view_system_tray_changed(self.refresh_view_system_tray) self.config.on_console_popup_changed(self.refresh_console_popup) - self.config.on_console_keygrab_changed(self.refresh_console_keygrab) + self.config.on_console_accels_changed(self.refresh_console_accels) self.config.on_console_scaling_changed(self.refresh_console_scaling) self.config.on_stats_update_interval_changed(self.refresh_update_interval) self.config.on_stats_history_length_changed(self.refresh_history_length) @@ -59,7 +61,7 @@ class vmmPreferences(gobject.GObject): self.refresh_update_interval() self.refresh_history_length() self.refresh_console_popup() - self.refresh_console_keygrab() + self.refresh_console_accels() self.refresh_console_scaling() self.refresh_sound_local() self.refresh_sound_remote() @@ -77,7 +79,7 @@ class vmmPreferences(gobject.GObject): "on_prefs_stats_update_interval_changed": self.change_update_interval, "on_prefs_stats_history_length_changed": self.change_history_length, "on_prefs_console_popup_changed": self.change_console_popup, - "on_prefs_console_keygrab_changed": self.change_console_keygrab, + "on_prefs_console_accels_toggled": self.change_console_accels, "on_prefs_console_scaling_changed": self.change_console_scaling, "on_prefs_close_clicked": self.close, "on_vmm_preferences_delete_event": self.close, @@ -127,10 +129,10 @@ class vmmPreferences(gobject.GObject): ignore3=None, ignore4=None): self.window.get_widget("prefs-console-popup").set_active( self.config.get_console_popup()) - def refresh_console_keygrab(self, ignore1=None, ignore2=None, + def refresh_console_accels(self, ignore1=None, ignore2=None, ignore3=None, ignore4=None): - self.window.get_widget("prefs-console-keygrab").set_active( - self.config.get_console_keygrab()) + self.window.get_widget("prefs-console-accels").set_active( + self.config.get_console_accels()) def refresh_console_scaling(self, ignore1=None, ignore2=None, ignore3=None, ignore4=None): val = self.config.get_console_scaling() @@ -249,8 +251,8 @@ class vmmPreferences(gobject.GObject): def change_console_popup(self, box): self.config.set_console_popup(box.get_active()) - def change_console_keygrab(self, box): - self.config.set_console_keygrab(box.get_active()) + def change_console_accels(self, src): + self.config.set_console_accels(src.get_active()) def change_console_scaling(self, box): self.config.set_console_scaling(box.get_active()) diff --git a/src/vmm-preferences.glade b/src/vmm-preferences.glade index 4685f5ed7..06ff38a37 100644 --- a/src/vmm-preferences.glade +++ b/src/vmm-preferences.glade @@ -322,7 +322,7 @@ True - 7 + 6 3 @@ -333,8 +333,8 @@ Always - 5 - 6 + 3 + 4 5 @@ -346,33 +346,6 @@ Always True prefs-console-scaling - - 4 - 5 - - - - - True - Never -When fullscreen -On mouse over - - - - 3 - 4 - 5 - - - - - True - 0 - Grab _keyboard accelerators: - True - prefs-console-keygrab - 2 3 @@ -441,8 +414,42 @@ For all domains - 6 - 7 + 4 + 5 + + + + + True + 6 + + + True + Force console menu accelerators while the console is active. Enabling this may overwrite keyboard interaction with the guest. + Force console keyboard shortcuts: + + + False + 0 + + + + + True + True + False + True + + + + False + 1 + + + + + 5 + 6