The attached patch adds an option for a virt-manager system tray icon. Here's a screenshot: http://fedorapeople.org/~crobinso/virt-manager/vmm-systray.png The icon can be used to quit the app, or start, stop, pause, or open a VM. Showing the icon needs to be opted in via Edit->Preferences. This should be handy for people that keep virt-manager running for a long time, and just need a simple interface to start/stop a VM, or open a graphical console. Questions or comments appreciated. Thanks, Cole
# HG changeset patch # User Cole Robinson <crobinso@xxxxxxxxxx> # Date 1248640996 14400 # Node ID 0a08550c10feaf20878cf6100119af0307872fc1 # Parent 860d7c2bfb8c22450e9028189f88c63fb13b3338 Add a system tray icon. The behavior is opt in via preferences, off by default. The icon allows starting, stopping, and pausing VMs, opening console/details, and quiting the entire app. diff -r 860d7c2bfb8c -r 0a08550c10fe src/virt-manager.schemas.in --- a/src/virt-manager.schemas.in Sun Jul 26 16:25:01 2009 -0400 +++ b/src/virt-manager.schemas.in Sun Jul 26 16:43:16 2009 -0400 @@ -170,6 +170,19 @@ </schema> <schema> + <key>/schemas/apps/::PACKAGE::/system-tray</key> + <applyto>/apps/::PACKAGE::/system-tray</applyto> + <owner>::PACKAGE::</owner> + <type>bool</type> + <default>0</default> + + <locale name="C"> + <short>Show system tray icon</short> + <long>Show system tray icon while app is running</long> + </locale> + </schema> + + <schema> <key>/schemas/apps/::PACKAGE::/paths/default-image-path</key> <applyto>/apps/::PACKAGE::/paths/default-image-path</applyto> <owner>::PACKAGE::</owner> diff -r 860d7c2bfb8c -r 0a08550c10fe src/virtManager/config.py --- a/src/virtManager/config.py Sun Jul 26 16:25:01 2009 -0400 +++ b/src/virtManager/config.py Sun Jul 26 16:43:16 2009 -0400 @@ -271,6 +271,13 @@ self.conf.set_value(self.conf_dir + "/paths/default-%s-path" % _type, folder) + def on_view_system_tray_changed(self, callback): + self.conf.notify_add(self.conf_dir + "/system-tray", callback) + def get_view_system_tray(self): + return self.conf.get_bool(self.conf_dir + "/system-tray") + def set_view_system_tray(self, val): + self.conf.set_bool(self.conf_dir + "/system-tray", val) + def on_vmlist_stats_type_changed(self, callback): self.conf.notify_add(self.conf_dir + "/vmlist-fields/stats_type", callback) diff -r 860d7c2bfb8c -r 0a08550c10fe src/virtManager/engine.py --- a/src/virtManager/engine.py Sun Jul 26 16:25:01 2009 -0400 +++ b/src/virtManager/engine.py Sun Jul 26 16:43:16 2009 -0400 @@ -40,6 +40,7 @@ from virtManager.create import vmmCreate from virtManager.host import vmmHost from virtManager.error import vmmErrorDialog +from virtManager.systray import vmmSystray import virtManager.util as util class vmmEngine(gobject.GObject): @@ -68,6 +69,8 @@ self.timer = None self.last_timeout = 0 + self.systray = None + self._tick_thread = None self._tick_thread_slow = False self._libvirt_support_threading = (libvirt.getVersion() >= 6000) @@ -79,6 +82,7 @@ self.windows = 0 self.netdevHelper = vmmNetDevHelper(self.config) + self.init_systray() self.config.on_stats_update_interval_changed(self.reschedule_timer) @@ -86,6 +90,22 @@ self.load_stored_uris() self.tick() + def init_systray(self): + if self.systray: + return + + self.systray = vmmSystray(self.config, self) + self.systray.connect("action-view-manager", self._do_show_manager) + self.systray.connect("action-suspend-domain", self._do_suspend_domain) + self.systray.connect("action-resume-domain", self._do_resume_domain) + self.systray.connect("action-run-domain", self._do_run_domain) + self.systray.connect("action-shutdown-domain", self._do_shutdown_domain) + self.systray.connect("action-reboot-domain", self._do_reboot_domain) + self.systray.connect("action-destroy-domain", self._do_destroy_domain) + self.systray.connect("action-show-console", self._do_show_console) + self.systray.connect("action-show-details", self._do_show_details) + self.systray.connect("action-exit-app", self._do_exit_app) + def load_stored_uris(self): uris = self.config.get_connections() if uris != None: diff -r 860d7c2bfb8c -r 0a08550c10fe src/virtManager/preferences.py --- a/src/virtManager/preferences.py Sun Jul 26 16:25:01 2009 -0400 +++ b/src/virtManager/preferences.py Sun Jul 26 16:43:16 2009 -0400 @@ -37,6 +37,7 @@ self.topwin = self.window.get_widget("vmm-preferences") self.topwin.hide() + 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_scaling_changed(self.refresh_console_scaling) @@ -47,6 +48,7 @@ self.config.on_stats_enable_disk_poll_changed(self.refresh_disk_poll) self.config.on_stats_enable_net_poll_changed(self.refresh_net_poll) + self.refresh_view_system_tray() self.refresh_update_interval() self.refresh_history_length() self.refresh_console_popup() @@ -58,6 +60,7 @@ self.refresh_net_poll() self.window.signal_autoconnect({ + "on_prefs_system_tray_toggled" : self.change_view_system_tray, "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, @@ -84,6 +87,11 @@ # Config Change Options # ######################### + def refresh_view_system_tray(self, ignore1=None, ignore2=None, + ignore3=None, ignore4=None): + val = self.config.get_view_system_tray() + self.window.get_widget("prefs-system-tray").set_active(bool(val)) + def refresh_update_interval(self, ignore1=None,ignore2=None,ignore3=None,ignore4=None): self.window.get_widget("prefs-stats-update-interval").set_value(self.config.get_stats_update_interval()) def refresh_history_length(self, ignore1=None,ignore2=None,ignore3=None,ignore4=None): @@ -116,6 +124,9 @@ ignore4=None): self.window.get_widget("prefs-stats-enable-net").set_active(self.config.get_stats_enable_net_poll()) + def change_view_system_tray(self, src): + self.config.set_view_system_tray(src.get_active()) + def change_update_interval(self, src): self.config.set_stats_update_interval(src.get_value_as_int()) def change_history_length(self, src): diff -r 860d7c2bfb8c -r 0a08550c10fe src/virtManager/systray.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/virtManager/systray.py Sun Jul 26 16:43:16 2009 -0400 @@ -0,0 +1,367 @@ +# +# Copyright (C) 2009 Red Hat, Inc. +# Copyright (C) 2009 Cole Robinson <crobinso@xxxxxxxxxx> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA. +# + +import gobject +import gtk +import gtk.glade + +class vmmSystray(gobject.GObject): + __gsignals__ = { + "action-view-manager": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, []), + "action-suspend-domain": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, (str, str)), + "action-resume-domain": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, (str, str)), + "action-run-domain": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, (str, str)), + "action-shutdown-domain": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, (str, str)), + "action-reboot-domain": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, (str, str)), + "action-destroy-domain": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, (str, str)), + "action-show-host": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, [str]), + "action-show-details": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, (str,str)), + "action-show-console": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, (str,str)), + "action-exit-app": (gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, []), + } + + def __init__(self, config, engine): + self.__gobject_init__() + + self.config = config + self.engine = engine + + self.conn_menuitems = {} + self.conn_vm_menuitems = {} + self.vm_action_dict = {} + self.systray_menu = None + self.systray_icon = None + + self.init_systray_menu() + + self.engine.connect("connection-added", self.conn_added) + self.engine.connect("connection-removed", self.conn_removed) + + self.config.on_view_system_tray_changed(self.show_systray) + self.show_systray() + + + # Initialization routines + + def init_systray_menu(self): + """ + Do we want notifications? + + Close App + Hide app? As in, only have systray active? is that possible? + Have one of those 'minimize to tray' notifications? + + """ + self.systray_menu = gtk.Menu() + + self.systray_menu.add(gtk.SeparatorMenuItem()) + exit_item = gtk.ImageMenuItem(gtk.STOCK_QUIT) + exit_item.connect("activate", self.exit_app) + self.systray_menu.add(exit_item) + self.systray_menu.show_all() + + def init_systray(self, show): + # Build the systray icon + if self.systray_icon: + return + + iconfile = self.config.get_icon_dir() + "/virt-manager-icon.svg" + self.systray_icon = gtk.StatusIcon() + self.systray_icon.set_visible(show) + self.systray_icon.set_property("file", iconfile) + self.systray_icon.connect("activate", self.systray_activate) + self.systray_icon.connect("popup-menu", self.systray_popup) + self.systray_icon.set_tooltip(_("Virtual Machine Manager")) + + def show_systray(self, ignore1=None, ignore2=None, ignore3=None, + ignore4=None): + do_show = self.config.get_view_system_tray() + + if not self.systray_icon: + self.init_systray(show=do_show) + else: + self.systray_icon.set_visible(do_show) + + def build_vm_menu(self, vm): + icon_size = gtk.ICON_SIZE_MENU + stop_icon = self.config.get_shutdown_icon_name() + + pause_item = gtk.ImageMenuItem(_("_Pause")) + pause_img = gtk.image_new_from_stock(gtk.STOCK_MEDIA_PAUSE, icon_size) + pause_item.set_image(pause_img) + pause_item.connect("activate", self.run_vm_action, + "action-suspend-domain", vm.get_uuid()) + + resume_item = gtk.ImageMenuItem(_("_Resume")) + resume_img = gtk.image_new_from_stock(gtk.STOCK_MEDIA_PAUSE, + icon_size) + resume_item.set_image(resume_img) + resume_item.connect("activate", self.run_vm_action, + "action-resume-domain", vm.get_uuid()) + + run_item = gtk.ImageMenuItem(_("_Run")) + run_img = gtk.image_new_from_stock(gtk.STOCK_MEDIA_PLAY, icon_size) + run_item.set_image(run_img) + run_item.connect("activate", self.run_vm_action, + "action-run-domain", vm.get_uuid()) + + # Shutdown menu + reboot_item = gtk.ImageMenuItem(_("_Reboot")) + reboot_img = gtk.image_new_from_icon_name(stop_icon, icon_size) + reboot_item.set_image(reboot_img) + reboot_item.connect("activate", self.run_vm_action, + "action-reboot-domain", vm.get_uuid()) + reboot_item.show() + + shutdown_item = gtk.ImageMenuItem(_("_Shut Down")) + shutdown_img = gtk.image_new_from_icon_name(stop_icon, icon_size) + shutdown_item.set_image(shutdown_img) + shutdown_item.connect("activate", self.run_vm_action, + "action-shutdown-domain", vm.get_uuid()) + shutdown_item.show() + + destroy_item = gtk.ImageMenuItem(_("_Force Off")) + destroy_img = gtk.image_new_from_icon_name(stop_icon, icon_size) + destroy_item.set_image(destroy_img) + destroy_item.show() + destroy_item.connect("activate", self.run_vm_action, + "action-destroy-domain", vm.get_uuid()) + + shutdown_menu = gtk.Menu() + shutdown_menu.add(reboot_item) + shutdown_menu.add(shutdown_item) + shutdown_menu.add(destroy_item) + shutdown_menu_item = gtk.ImageMenuItem(_("_Shut Down")) + shutdown_menu_img = gtk.image_new_from_icon_name(stop_icon, icon_size) + shutdown_menu_item.set_image(shutdown_menu_img) + shutdown_menu_item.set_submenu(shutdown_menu) + + sep = gtk.SeparatorMenuItem() + + open_item = gtk.ImageMenuItem("gtk-open") + open_item.show() + open_item.connect("activate", self.run_vm_action, + "action-show-console", vm.get_uuid()) + + vm_action_dict = {} + vm_action_dict["run"] = run_item + vm_action_dict["pause"] = pause_item + vm_action_dict["resume"] = resume_item + vm_action_dict["shutdown_menu"] = shutdown_menu_item + vm_action_dict["reboot"] = reboot_item + vm_action_dict["shutdown"] = shutdown_item + vm_action_dict["destroy"] = destroy_item + vm_action_dict["sep"] = sep + vm_action_dict["open"] = open_item + + menu = gtk.Menu() + + for key in ["run", "pause", "resume", "shutdown_menu", "sep", "open"]: + item = vm_action_dict[key] + item.show_all() + menu.add(vm_action_dict[key]) + + return menu, vm_action_dict + + # Helper functions + def _get_vm_menu_item(self, vm): + uuid = vm.get_uuid() + uri = vm.get_connection().get_uri() + + if self.conn_vm_menuitems.has_key(uri): + if self.conn_vm_menuitems[uri].has_key(uuid): + return self.conn_vm_menuitems[uri][uuid] + return None + + def _set_vm_status_icon(self, vm, menu_item): + image = gtk.image_new_from_pixbuf(vm.run_status_icon()) + image.set_sensitive(vm.is_active()) + menu_item.set_image(image) + + # Listeners + + def systray_activate(self, widget): + self.emit("action-view-manager") + + def systray_popup(self, widget, button, event_time): + if button != 3: + return + + self.systray_menu.popup(None, None, None, 0, event_time) + + def conn_added(self, engine, conn): + conn.connect("vm-added", self.vm_added) + conn.connect("vm-removed", self.vm_removed) + conn.connect("state-changed", self.conn_state_changed) + + if self.conn_menuitems.has_key(conn.get_uri()): + return + + menu_item = gtk.MenuItem(conn.get_pretty_desc_inactive()) + menu_item.show() + vm_submenu = gtk.Menu() + vm_submenu.show() + menu_item.set_submenu(vm_submenu) + + self.conn_menuitems[conn.get_uri()] = menu_item + self.conn_vm_menuitems[conn.get_uri()] = {} + + # Insert conn in list before 'Quit' item + idx = len(self.systray_menu) - 2 + self.systray_menu.insert(menu_item, idx) + + self.conn_state_changed(conn) + self.populate_vm_list(conn) + + def conn_removed(self, engine, conn): + if not self.conn_menuitems.has_key(conn.get_uri()): + return + + menu_item = self.conn_menuitems[conn.get_uri()] + self.systray_menu.remove(menu_item) + del(self.conn_menuitems[conn.get_uri()]) + self.conn_vm_menuitems[conn.get_uri()] = {} + + def conn_state_changed(self, conn): + # XXX: Even 'paused' conn? + sensitive = conn.is_active() + menu_item = self.conn_menuitems[conn.get_uri()] + menu_item.set_sensitive(sensitive) + + def populate_vm_list(self, conn): + uri = conn.get_uri() + conn_menu_item = self.conn_menuitems[uri] + vm_submenu = conn_menu_item.get_submenu() + + # Empty conn menu + for c in vm_submenu.get_children(): + vm_submenu.remove(c) + + vm_mappings = {} + for vm in conn.vms.values(): + vm_mappings[vm.get_name()] = vm.get_uuid() + + vm_names = vm_mappings.keys() + vm_names.sort() + + if len(vm_names) == 0: + menu_item = gtk.MenuItem(_("No virtual machines")) + menu_item.set_sensitive(False) + vm_submenu.insert(menu_item, 0) + return + + for i in range(0, len(vm_names)): + name = vm_names[i] + uuid = vm_mappings[name] + if self.conn_vm_menuitems[uri].has_key(uuid): + vm_item = self.conn_vm_menuitems[uri][uuid] + vm_submenu.insert(vm_item, i) + + def vm_added(self, conn, uri, uuid): + vm = conn.get_vm(uuid) + if not vm: + return + vm.connect("status-changed", self.vm_state_changed) + + vm_mappings = self.conn_vm_menuitems[uri] + if vm_mappings.has_key(uuid): + return + + # Build VM list entry + menu_item = gtk.ImageMenuItem(vm.get_name()) + vm_mappings[uuid] = menu_item + vm_action_menu, vm_action_dict = self.build_vm_menu(vm) + menu_item.set_submenu(vm_action_menu) + self.vm_action_dict[uuid] = vm_action_dict + + # Add VM to menu list + self.populate_vm_list(conn) + + # Update state + self.vm_state_changed(vm) + menu_item.show() + + def vm_removed(self, conn, uri, uuid): + vm_mappings = self.conn_vm_menuitems[uri] + if not vm_mappings: + return + + if vm_mappings.has_key(uuid): + conn_item = self.conn_menuitems[uri] + vm_menu_item = vm_mappings[uuid] + vm_menu = conn_item.get_submenu() + vm_menu.remove(vm_menu_item) + del(vm_mappings[uuid]) + + if len(vm_menu.get_children()) == 0: + placeholder = gtk.MenuItem(_("No VMs available")) + placeholder.show() + placeholder.set_sensitive(False) + vm_menu.add(placeholder) + + def vm_state_changed(self, vm, ignore=None): + menu_item = self._get_vm_menu_item(vm) + if not menu_item: + return + + self._set_vm_status_icon(vm, menu_item) + + # Update action widget states + actions = self.vm_action_dict[vm.get_uuid()] + + is_paused = vm.is_paused() + actions["run"].set_sensitive(vm.is_runable()) + actions["pause"].set_sensitive(vm.is_pauseable()) + actions["resume"].set_sensitive(vm.is_paused()) + actions["shutdown_menu"].set_sensitive(vm.is_active()) + actions["shutdown"].set_sensitive(vm.is_stoppable()) + actions["reboot"].set_sensitive(vm.is_stoppable()) + actions["destroy"].set_sensitive(vm.is_destroyable()) + + actions["pause"].set_property("visible", not is_paused) + actions["resume"].set_property("visible", is_paused) + + def run_vm_action(self, ignore, signal_name, uuid): + uri = None + for tmpuri, vm_mappings in self.conn_vm_menuitems.items(): + if vm_mappings.get(uuid): + uri = tmpuri + break + + if not uri: + return + + self.emit(signal_name, uri, uuid) + + def exit_app(self, ignore): + self.emit("action-exit-app") + +gobject.type_register(vmmSystray) diff -r 860d7c2bfb8c -r 0a08550c10fe src/vmm-preferences.glade --- a/src/vmm-preferences.glade Sun Jul 26 16:25:01 2009 -0400 +++ b/src/vmm-preferences.glade Sun Jul 26 16:43:16 2009 -0400 @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> -<!--Generated with glade3 3.4.5 on Wed Jul 22 23:26:58 2009 --> +<!--Generated with glade3 3.4.5 on Fri Jul 24 11:42:36 2009 --> <glade-interface> <widget class="GtkWindow" id="vmm-preferences"> <property name="title" translatable="yes">Preferences</property> @@ -17,6 +17,70 @@ <property name="can_focus">True</property> <property name="border_width">3</property> <child> + <widget class="GtkVBox" id="vbox5"> + <property name="visible">True</property> + <property name="border_width">6</property> + <child> + <widget class="GtkFrame" id="frame5"> + <property name="visible">True</property> + <property name="label_xalign">0</property> + <property name="shadow_type">GTK_SHADOW_NONE</property> + <child> + <widget class="GtkAlignment" id="alignment7"> + <property name="visible">True</property> + <property name="left_padding">12</property> + <child> + <widget class="GtkTable" id="table5"> + <property name="visible">True</property> + <property name="n_rows">2</property> + <property name="column_spacing">6</property> + <property name="row_spacing">6</property> + <child> + <placeholder/> + </child> + <child> + <widget class="GtkCheckButton" id="prefs-system-tray"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Enable system tray icon</property> + <property name="response_id">0</property> + <property name="draw_indicator">True</property> + <signal name="toggled" handler="on_prefs_system_tray_toggled"/> + </widget> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label12"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>General</b></property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="type">label_item</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label11"> + <property name="visible">True</property> + <property name="label" translatable="yes">General</property> + </widget> + <packing> + <property name="type">tab</property> + <property name="tab_fill">False</property> + </packing> + </child> + <child> <widget class="GtkVBox" id="vbox2"> <property name="visible">True</property> <property name="border_width">6</property> @@ -38,34 +102,27 @@ <property name="column_spacing">3</property> <property name="row_spacing">3</property> <child> - <widget class="GtkLabel" id="label6"> + <widget class="GtkLabel" id="label9"> <property name="visible">True</property> <property name="xalign">0</property> - <property name="label" translatable="yes">Update status every</property> - </widget> - </child> - <child> - <widget class="GtkLabel" id="label7"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Maintain history of</property> + <property name="label" translatable="yes">samples</property> </widget> <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> <property name="top_attach">1</property> <property name="bottom_attach">2</property> </packing> </child> <child> - <widget class="GtkSpinButton" id="prefs-stats-update-interval"> + <widget class="GtkLabel" id="label8"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="adjustment">0 0 60 1 5 0</property> - <signal name="value_changed" handler="on_prefs_stats_update_interval_changed"/> + <property name="xalign">0</property> + <property name="label" translatable="yes">seconds</property> </widget> <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="x_options">GTK_FILL</property> + <property name="left_attach">2</property> + <property name="right_attach">3</property> </packing> </child> <child> @@ -85,29 +142,36 @@ </packing> </child> <child> - <widget class="GtkLabel" id="label8"> + <widget class="GtkSpinButton" id="prefs-stats-update-interval"> <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">seconds</property> + <property name="can_focus">True</property> + <property name="adjustment">0 0 60 1 5 0</property> + <signal name="value_changed" handler="on_prefs_stats_update_interval_changed"/> </widget> <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="x_options">GTK_FILL</property> </packing> </child> <child> - <widget class="GtkLabel" id="label9"> + <widget class="GtkLabel" id="label7"> <property name="visible">True</property> <property name="xalign">0</property> - <property name="label" translatable="yes">samples</property> + <property name="label" translatable="yes">Maintain history of</property> </widget> <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> <property name="top_attach">1</property> <property name="bottom_attach">2</property> </packing> </child> + <child> + <widget class="GtkLabel" id="label6"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Update status every</property> + </widget> + </child> </widget> </child> </widget> @@ -156,25 +220,19 @@ <placeholder/> </child> <child> - <widget class="GtkLabel" id="label13"> + <widget class="GtkCheckButton" id="prefs-stats-enable-net"> <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Disk I/O</property> + <property name="can_focus">True</property> + <property name="response_id">0</property> + <property name="draw_indicator">True</property> + <signal name="toggled" handler="on_prefs_stats_enable_net_toggled"/> </widget> <packing> - <property name="x_options">GTK_FILL</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label14"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Network I/O</property> - </widget> - <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> <property name="top_attach">1</property> <property name="bottom_attach">2</property> - <property name="x_options">GTK_FILL</property> + <property name="x_options">GTK_EXPAND</property> </packing> </child> <child> @@ -192,19 +250,25 @@ </packing> </child> <child> - <widget class="GtkCheckButton" id="prefs-stats-enable-net"> + <widget class="GtkLabel" id="label14"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="response_id">0</property> - <property name="draw_indicator">True</property> - <signal name="toggled" handler="on_prefs_stats_enable_net_toggled"/> + <property name="xalign">0</property> + <property name="label" translatable="yes">Network I/O</property> </widget> <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> <property name="top_attach">1</property> <property name="bottom_attach">2</property> - <property name="x_options">GTK_EXPAND</property> + <property name="x_options">GTK_FILL</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="label13"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Disk I/O</property> + </widget> + <packing> + <property name="x_options">GTK_FILL</property> </packing> </child> </widget> @@ -228,6 +292,9 @@ </packing> </child> </widget> + <packing> + <property name="position">1</property> + </packing> </child> <child> <widget class="GtkLabel" id="label2"> @@ -236,6 +303,7 @@ </widget> <packing> <property name="type">tab</property> + <property name="position">1</property> <property name="tab_fill">False</property> </packing> </child> @@ -259,35 +327,28 @@ <property name="n_rows">6</property> <property name="row_spacing">3</property> <child> - <widget class="GtkComboBox" id="prefs-console-popup"> + <widget class="GtkComboBox" id="prefs-console-scaling"> <property name="visible">True</property> <property name="items" translatable="yes">Never -For all new domains -For all domains</property> - <signal name="changed" handler="on_prefs_console_popup_changed"/> +Fullscreen only +Always</property> + <signal name="changed" handler="on_prefs_console_scaling_changed"/> </widget> <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> + <property name="top_attach">5</property> + <property name="bottom_attach">6</property> <property name="x_padding">5</property> </packing> </child> <child> - <widget class="GtkLabel" id="label5"> + <widget class="GtkLabel" id="label17"> <property name="visible">True</property> <property name="xalign">0</property> - <property name="label" translatable="yes">Automatically open consoles:</property> - </widget> - </child> - <child> - <widget class="GtkLabel" id="label15"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Grab keyboard input:</property> + <property name="label" translatable="yes">Graphical Console Scaling:</property> </widget> <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> </packing> </child> <child> @@ -305,27 +366,34 @@ </packing> </child> <child> - <widget class="GtkLabel" id="label17"> + <widget class="GtkLabel" id="label15"> <property name="visible">True</property> <property name="xalign">0</property> - <property name="label" translatable="yes">Graphical Console Scaling:</property> + <property name="label" translatable="yes">Grab keyboard input:</property> </widget> <packing> - <property name="top_attach">4</property> - <property name="bottom_attach">5</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> </packing> </child> <child> - <widget class="GtkComboBox" id="prefs-console-scaling"> + <widget class="GtkLabel" id="label5"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Automatically open consoles:</property> + </widget> + </child> + <child> + <widget class="GtkComboBox" id="prefs-console-popup"> <property name="visible">True</property> <property name="items" translatable="yes">Never -Fullscreen only -Always</property> - <signal name="changed" handler="on_prefs_console_scaling_changed"/> +For all new domains +For all domains</property> + <signal name="changed" handler="on_prefs_console_popup_changed"/> </widget> <packing> - <property name="top_attach">5</property> - <property name="bottom_attach">6</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> <property name="x_padding">5</property> </packing> </child> @@ -363,13 +431,6 @@ <property name="n_rows">2</property> <property name="column_spacing">8</property> <child> - <widget class="GtkLabel" id="label16"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Install Audio Device:</property> - </widget> - </child> - <child> <widget class="GtkAlignment" id="alignment6"> <property name="visible">True</property> <property name="left_padding">12</property> @@ -407,6 +468,13 @@ <property name="bottom_attach">2</property> </packing> </child> + <child> + <widget class="GtkLabel" id="label16"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Install Audio Device:</property> + </widget> + </child> </widget> </child> </widget> @@ -429,7 +497,7 @@ </child> </widget> <packing> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> <child> @@ -439,7 +507,7 @@ </widget> <packing> <property name="type">tab</property> - <property name="position">1</property> + <property name="position">2</property> <property name="tab_fill">False</property> </packing> </child>
_______________________________________________ et-mgmt-tools mailing list et-mgmt-tools@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/et-mgmt-tools