Properly cleanup all dialogs
On app close, all dialogs are properly cleaned up so there are no dangling references and python can garbage collect. While this isn't that important when the app shuts down, it ensures that lifecycle changes while the app is running (vm start/stop/remove, conn start/stop/remove) have the infrastructure to properly release resources.
This commit is contained in:
parent
ff3606e740
commit
f2781ee62a
|
@ -41,8 +41,8 @@ class vmmGObject(gobject.GObject):
|
|||
self._gobject_timeouts = []
|
||||
self._gconf_handles = []
|
||||
|
||||
self._object_key = str(self)
|
||||
self.config.add_object(self._object_key)
|
||||
self.object_key = str(self)
|
||||
self.config.add_object(self.object_key)
|
||||
|
||||
def cleanup(self):
|
||||
# Do any cleanup required to drop reference counts so object is
|
||||
|
@ -78,6 +78,11 @@ class vmmGObject(gobject.GObject):
|
|||
gobject.source_remove(handle)
|
||||
self._gobject_timeouts.remove(handle)
|
||||
|
||||
def _printtrace(self, msg):
|
||||
import traceback
|
||||
print "%s (%s %s)\n:%s" % (msg, self.object_key, self.refcount(),
|
||||
"".join(traceback.format_stack()))
|
||||
|
||||
def refcount(self):
|
||||
# Function generates 2 temporary refs, so adjust total accordingly
|
||||
return (sys.getrefcount(self) - 2)
|
||||
|
@ -91,9 +96,9 @@ class vmmGObject(gobject.GObject):
|
|||
getattr(gobject.GObject, "__del__")(self)
|
||||
|
||||
try:
|
||||
self.config.remove_object(self._object_key)
|
||||
self.config.remove_object(self.object_key)
|
||||
except:
|
||||
logging.exception("Error removing %s" % self._object_key)
|
||||
logging.exception("Error removing %s" % self.object_key)
|
||||
|
||||
class vmmGObjectUI(vmmGObject):
|
||||
def __init__(self, filename, windowname):
|
||||
|
|
|
@ -131,8 +131,33 @@ class vmmCloneVM(vmmGObjectUI):
|
|||
self.change_mac_close()
|
||||
self.change_storage_close()
|
||||
self.topwin.hide()
|
||||
|
||||
self.orig_vm = None
|
||||
self.clone_design = None
|
||||
self.storage_list = {}
|
||||
self.target_list = []
|
||||
self.net_list = {}
|
||||
self.mac_list = []
|
||||
|
||||
return 1
|
||||
|
||||
def cleanup(self):
|
||||
self.close()
|
||||
|
||||
self.conn = None
|
||||
|
||||
self.change_mac.destroy()
|
||||
self.change_mac = None
|
||||
|
||||
self.change_storage.destroy()
|
||||
self.change_storage = None
|
||||
|
||||
if self.storage_browser:
|
||||
self.storage_browser.cleanup()
|
||||
self.storage_browser = None
|
||||
|
||||
vmmGObjectUI.cleanup(self)
|
||||
|
||||
def change_mac_close(self, ignore1=None, ignore2=None):
|
||||
self.change_mac.hide()
|
||||
return 1
|
||||
|
|
|
@ -146,6 +146,7 @@ class vmmConnection(vmmGObject):
|
|||
self.hostinfo = None
|
||||
|
||||
self.hal_helper_remove_sig = None
|
||||
self.hal_handles = []
|
||||
|
||||
self.netdev_initialized = False
|
||||
self.netdev_error = ""
|
||||
|
@ -164,6 +165,7 @@ class vmmConnection(vmmGObject):
|
|||
sig = hal_helper.connect("device-removed",
|
||||
self._haldev_removed)
|
||||
self.hal_helper_remove_sig = sig
|
||||
self.hal_handles.append(sig)
|
||||
|
||||
def _init_netdev(self):
|
||||
"""
|
||||
|
@ -186,7 +188,8 @@ class vmmConnection(vmmGObject):
|
|||
else:
|
||||
error = hal_helper.get_init_error()
|
||||
if not error:
|
||||
hal_helper.connect("netdev-added", self._netdev_added)
|
||||
self.hal_handles.append(
|
||||
hal_helper.connect("netdev-added", self._netdev_added))
|
||||
self._set_hal_remove_sig(hal_helper)
|
||||
|
||||
else:
|
||||
|
@ -225,7 +228,8 @@ class vmmConnection(vmmGObject):
|
|||
else:
|
||||
error = hal_helper.get_init_error()
|
||||
if not error:
|
||||
hal_helper.connect("optical-added", self._optical_added)
|
||||
self.hal_handles.append(
|
||||
hal_helper.connect("optical-added", self._optical_added))
|
||||
self._set_hal_remove_sig(hal_helper)
|
||||
|
||||
else:
|
||||
|
@ -922,6 +926,16 @@ class vmmConnection(vmmGObject):
|
|||
|
||||
self._change_state(self.STATE_DISCONNECTED)
|
||||
|
||||
def cleanup(self):
|
||||
# Do this first, so signals are unregistered before we change state
|
||||
vmmGObject.cleanup(self)
|
||||
self.close()
|
||||
|
||||
hal_helper = self.get_hal_helper()
|
||||
if hal_helper:
|
||||
for h in self.hal_handles:
|
||||
hal_helper.disconnect(h)
|
||||
|
||||
def _open_dev_conn(self, uri):
|
||||
"""
|
||||
Allow using virtinsts connection hacking to fake capabilities
|
||||
|
|
|
@ -155,9 +155,33 @@ class vmmCreate(vmmGObjectUI):
|
|||
|
||||
if self.config_window:
|
||||
self.config_window.close()
|
||||
if self.storage_browser:
|
||||
self.storage_browser.close()
|
||||
|
||||
return 1
|
||||
|
||||
def cleanup(self):
|
||||
self.close()
|
||||
self.remove_conn()
|
||||
|
||||
self.conn = None
|
||||
self.caps = None
|
||||
self.capsguest = None
|
||||
self.capsdomain = None
|
||||
|
||||
self.guest = None
|
||||
self.disk = None
|
||||
self.nic = None
|
||||
|
||||
try:
|
||||
if self.storage_browser:
|
||||
self.storage_browser.cleanup()
|
||||
self.storage_browser = None
|
||||
except:
|
||||
logging.exception("Error cleaning up create")
|
||||
|
||||
vmmGObjectUI.cleanup(self)
|
||||
|
||||
def remove_timers(self):
|
||||
try:
|
||||
if self.host_storage_timer:
|
||||
|
@ -166,15 +190,20 @@ class vmmCreate(vmmGObjectUI):
|
|||
except:
|
||||
pass
|
||||
|
||||
def remove_conn(self):
|
||||
if not self.conn:
|
||||
return
|
||||
|
||||
for signal in self.conn_signals:
|
||||
self.conn.disconnect(signal)
|
||||
self.conn_signals = []
|
||||
self.conn = None
|
||||
|
||||
def set_conn(self, newconn, force_validate=False):
|
||||
if self.conn == newconn and not force_validate:
|
||||
return
|
||||
|
||||
if self.conn:
|
||||
for signal in self.conn_signals:
|
||||
self.conn.disconnect(signal)
|
||||
self.conn_signals = []
|
||||
|
||||
self.remove_conn()
|
||||
self.conn = newconn
|
||||
if self.conn:
|
||||
self.set_conn_state()
|
||||
|
|
|
@ -153,6 +153,26 @@ class vmmCreateInterface(vmmGObjectUI):
|
|||
|
||||
return 1
|
||||
|
||||
def cleanup(self):
|
||||
self.close()
|
||||
|
||||
try:
|
||||
self.conn = None
|
||||
self.interface = None
|
||||
|
||||
self.ip_config.destroy()
|
||||
self.ip_config = None
|
||||
|
||||
self.bridge_config.destroy()
|
||||
self.bridge_config = None
|
||||
|
||||
self.bond_config.destroy()
|
||||
self.bond_config = None
|
||||
except:
|
||||
logging.exception("Error cleaning up addiface")
|
||||
|
||||
vmmGObjectUI.cleanup(self)
|
||||
|
||||
###########################
|
||||
# Initialization routines #
|
||||
###########################
|
||||
|
|
|
@ -75,6 +75,21 @@ class vmmCreateNetwork(vmmGObjectUI):
|
|||
self.reset_state()
|
||||
self.topwin.present()
|
||||
|
||||
def is_visible(self):
|
||||
if self.topwin.flags() & gtk.VISIBLE:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def close(self, ignore1=None, ignore2=None):
|
||||
self.topwin.hide()
|
||||
return 1
|
||||
|
||||
def cleanup(self):
|
||||
self.close()
|
||||
self.conn = None
|
||||
|
||||
vmmGObjectUI.cleanup(self)
|
||||
|
||||
def set_initial_state(self):
|
||||
notebook = self.window.get_widget("create-pages")
|
||||
notebook.set_show_tabs(False)
|
||||
|
@ -310,14 +325,6 @@ class vmmCreateNetwork(vmmGObjectUI):
|
|||
self.window.get_widget("create-finish").show()
|
||||
self.window.get_widget("create-finish").grab_focus()
|
||||
|
||||
def close(self, ignore1=None, ignore2=None):
|
||||
self.topwin.hide()
|
||||
return 1
|
||||
|
||||
def is_visible(self):
|
||||
if self.topwin.flags() & gtk.VISIBLE:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def finish(self, ignore=None):
|
||||
name = self.get_config_name()
|
||||
|
|
|
@ -111,6 +111,14 @@ class vmmCreatePool(vmmGObjectUI):
|
|||
self.topwin.hide()
|
||||
return 1
|
||||
|
||||
def cleanup(self):
|
||||
self.close()
|
||||
|
||||
self.conn = None
|
||||
self._pool = None
|
||||
|
||||
vmmGObjectUI.cleanup(self)
|
||||
|
||||
def set_initial_state(self):
|
||||
self.window.get_widget("pool-pages").set_show_tabs(False)
|
||||
|
||||
|
|
|
@ -83,6 +83,14 @@ class vmmDeleteDialog(vmmGObjectUI):
|
|||
self.conn = None
|
||||
return 1
|
||||
|
||||
def cleanup(self):
|
||||
self.close()
|
||||
|
||||
self.vm = None
|
||||
self.conn = None
|
||||
|
||||
vmmGObjectUI.cleanup(self)
|
||||
|
||||
def reset_state(self):
|
||||
|
||||
# Set VM name in title'
|
||||
|
|
|
@ -45,10 +45,11 @@ from virtManager.create import vmmCreate
|
|||
from virtManager.host import vmmHost
|
||||
from virtManager.error import vmmErrorDialog
|
||||
from virtManager.systray import vmmSystray
|
||||
import virtManager.uihelpers as uihelpers
|
||||
import virtManager.util as util
|
||||
|
||||
# Enable this to get a report of leaked objects on app shutdown
|
||||
debug_ref_leaks = False
|
||||
debug_ref_leaks = True
|
||||
|
||||
def default_uri():
|
||||
tryuri = None
|
||||
|
@ -246,8 +247,10 @@ class vmmEngine(vmmGObject):
|
|||
|
||||
self.init_systray()
|
||||
|
||||
self.config.on_stats_update_interval_changed(self.reschedule_timer)
|
||||
self.config.on_view_system_tray_changed(self.system_tray_changed)
|
||||
self.add_gconf_handle(
|
||||
self.config.on_stats_update_interval_changed(self.reschedule_timer))
|
||||
self.add_gconf_handle(
|
||||
self.config.on_view_system_tray_changed(self.system_tray_changed))
|
||||
|
||||
self.schedule_timer()
|
||||
self.load_stored_uris()
|
||||
|
@ -349,8 +352,6 @@ class vmmEngine(vmmGObject):
|
|||
|
||||
def connect_to_uri(self, uri, readOnly=None, autoconnect=False,
|
||||
do_start=True):
|
||||
self.windowConnect = None
|
||||
|
||||
try:
|
||||
conn = self._check_connection(uri)
|
||||
if not conn:
|
||||
|
@ -368,10 +369,9 @@ class vmmEngine(vmmGObject):
|
|||
def _do_connect(self, src_ignore, uri):
|
||||
return self.connect_to_uri(uri)
|
||||
|
||||
def _connect_cancelled(self, connect_ignore):
|
||||
self.windowConnect = None
|
||||
def _connect_cancelled(self, src):
|
||||
if len(self.connections.keys()) == 0:
|
||||
self.exit_app()
|
||||
self.exit_app(src)
|
||||
|
||||
|
||||
def _do_vm_removed(self, connection, hvuri, vmuuid):
|
||||
|
@ -393,10 +393,6 @@ class vmmEngine(vmmGObject):
|
|||
self.connections[hvuri]["windowDetails"][vmuuid].cleanup()
|
||||
del(self.connections[hvuri]["windowDetails"][vmuuid])
|
||||
|
||||
if self.connections[hvuri]["windowHost"] is not None:
|
||||
self.connections[hvuri]["windowHost"].close()
|
||||
self.connections[hvuri]["windowHost"] = None
|
||||
|
||||
if (self.windowCreate and
|
||||
self.windowCreate.conn and
|
||||
self.windowCreate.conn.get_uri() == hvuri):
|
||||
|
@ -461,18 +457,79 @@ class vmmEngine(vmmGObject):
|
|||
def decrement_window_counter(self):
|
||||
self.windows -= 1
|
||||
logging.debug("window counter decremented to %s" % self.windows)
|
||||
|
||||
# Don't exit if system tray is enabled
|
||||
if self.windows <= 0 and not self.systray.is_visible():
|
||||
if (self.windows <= 0 and
|
||||
self.systray and
|
||||
not self.systray.is_visible()):
|
||||
self.exit_app()
|
||||
|
||||
def exit_app(self, ignore_src=None):
|
||||
conns = self.connections.values()
|
||||
for conn in conns:
|
||||
conn["connection"].close()
|
||||
self.connections = {}
|
||||
def cleanup(self):
|
||||
try:
|
||||
vmmGObject.cleanup(self)
|
||||
uihelpers.cleanup()
|
||||
self.err = None
|
||||
|
||||
if self.timer != None:
|
||||
gobject.source_remove(self.timer)
|
||||
|
||||
if self.systray:
|
||||
self.systray.cleanup()
|
||||
self.systray = None
|
||||
|
||||
self.get_manager()
|
||||
if self.windowManager:
|
||||
self.windowManager.cleanup()
|
||||
self.windowManager = None
|
||||
|
||||
if self.windowPreferences:
|
||||
self.windowPreferences.cleanup()
|
||||
self.windowPreferences = None
|
||||
|
||||
if self.windowAbout:
|
||||
self.windowAbout.cleanup()
|
||||
self.windowAbout = None
|
||||
|
||||
if self.windowConnect:
|
||||
self.windowConnect.cleanup()
|
||||
self.windowConnect = None
|
||||
|
||||
if self.windowCreate:
|
||||
self.windowCreate.cleanup()
|
||||
self.windowCreate = None
|
||||
|
||||
if self.windowMigrate:
|
||||
self.windowMigrate.cleanup()
|
||||
self.windowMigrate = None
|
||||
|
||||
# Do this last, so any manually 'disconnected' signals
|
||||
# take precedence over cleanup signal removal
|
||||
for uri in self.connections:
|
||||
self.cleanup_connection(uri)
|
||||
self.connections = {}
|
||||
except:
|
||||
logging.exception("Error cleaning up engine")
|
||||
|
||||
def exit_app(self, src=None):
|
||||
if self.err is None:
|
||||
# Already in cleanup
|
||||
return
|
||||
|
||||
self.cleanup()
|
||||
|
||||
if debug_ref_leaks:
|
||||
for name in self.config.get_objects():
|
||||
objs = self.config.get_objects()
|
||||
if src and src.object_key in objs:
|
||||
# Whatever UI initiates the app exit will always appear
|
||||
# to leak
|
||||
logging.debug("Exitting app from %s, skipping leak check" %
|
||||
src.object_key)
|
||||
objs.remove(src.object_key)
|
||||
|
||||
# Engine will always appear to leak
|
||||
objs.remove(self.object_key)
|
||||
|
||||
for name in objs:
|
||||
logging.debug("Leaked %s" % name)
|
||||
|
||||
logging.debug("Exiting app normally.")
|
||||
|
@ -502,13 +559,28 @@ class vmmEngine(vmmGObject):
|
|||
|
||||
return conn
|
||||
|
||||
def cleanup_connection(self, uri):
|
||||
try:
|
||||
if self.connections[uri]["windowHost"]:
|
||||
self.connections[uri]["windowHost"].cleanup()
|
||||
if self.connections[uri]["windowClone"]:
|
||||
self.connections[uri]["windowClone"].cleanup()
|
||||
|
||||
details = self.connections[uri]["windowDetails"]
|
||||
for win in details.values():
|
||||
win.cleanup()
|
||||
|
||||
self.connections[uri]["connection"].cleanup()
|
||||
except:
|
||||
logging.exception("Error cleaning up conn in engine")
|
||||
|
||||
|
||||
def remove_connection(self, uri):
|
||||
conn = self.connections[uri]["connection"]
|
||||
conn.close()
|
||||
del self.connections[uri]
|
||||
self.cleanup_connection(uri)
|
||||
del(self.connections[uri])
|
||||
|
||||
self.emit("connection-removed", uri)
|
||||
self.config.remove_connection(conn.get_uri())
|
||||
self.config.remove_connection(uri)
|
||||
|
||||
def connect(self, name, callback, *args):
|
||||
handle_id = vmmGObject.connect(self, name, callback, *args)
|
||||
|
@ -683,7 +755,8 @@ class vmmEngine(vmmGObject):
|
|||
|
||||
def _do_show_manager(self, src):
|
||||
try:
|
||||
self.get_manager().show()
|
||||
manager = self.get_manager()
|
||||
manager.show()
|
||||
except Exception, e:
|
||||
if not src:
|
||||
raise
|
||||
|
|
|
@ -312,6 +312,43 @@ class vmmHost(vmmGObjectUI):
|
|||
self.engine.decrement_window_counter()
|
||||
return 1
|
||||
|
||||
def cleanup(self):
|
||||
self.close()
|
||||
|
||||
try:
|
||||
self.conn = None
|
||||
self.engine = None
|
||||
|
||||
|
||||
if self.addnet:
|
||||
self.addnet.cleanup()
|
||||
self.addnet = None
|
||||
|
||||
if self.addpool:
|
||||
self.addpool.cleanup()
|
||||
self.addpool = None
|
||||
|
||||
if self.addvol:
|
||||
self.addvol.cleanup()
|
||||
self.addvol = None
|
||||
|
||||
if self.addinterface:
|
||||
self.addinterface.cleanup()
|
||||
self.addinterface = None
|
||||
|
||||
self.volmenu.destroy()
|
||||
self.volmenu = None
|
||||
|
||||
self.cpu_usage_graph.destroy()
|
||||
self.cpu_usage_graph = None
|
||||
|
||||
self.memory_usage_graph.destroy()
|
||||
self.memory_usage_graph = None
|
||||
except:
|
||||
logging.exception("Error cleaning up host dialog")
|
||||
|
||||
vmmGObjectUI.cleanup(self)
|
||||
|
||||
def show_help(self, src_ignore):
|
||||
self.emit("action-show-help", "virt-manager-host-window")
|
||||
|
||||
|
|
|
@ -129,17 +129,18 @@ class vmmManager(vmmGObjectUI):
|
|||
self.topwin.set_default_size(w or 550, h or 550)
|
||||
self.prev_position = None
|
||||
|
||||
self.init_vmlist()
|
||||
self.init_stats()
|
||||
self.init_toolbar()
|
||||
|
||||
self.vmmenu = gtk.Menu()
|
||||
self.vmmenushutdown = gtk.Menu()
|
||||
self.vmmenu_items = {}
|
||||
self.vmmenushutdown_items = {}
|
||||
self.connmenu = gtk.Menu()
|
||||
self.connmenu_items = {}
|
||||
self.init_context_menus()
|
||||
|
||||
# There seem to be ref counting issues with calling
|
||||
# list.get_column, so avoid it
|
||||
self.diskcol = None
|
||||
self.netcol = None
|
||||
self.cpucol = None
|
||||
|
||||
self.window.signal_autoconnect({
|
||||
"on_menu_view_cpu_usage_activate": (self.toggle_stats_visible,
|
||||
|
@ -171,7 +172,12 @@ class vmmManager(vmmGObjectUI):
|
|||
"on_menu_edit_preferences_activate": self.show_preferences,
|
||||
"on_menu_help_about_activate": self.show_about,
|
||||
"on_menu_help_activate": self.show_help,
|
||||
})
|
||||
})
|
||||
|
||||
self.init_vmlist()
|
||||
self.init_stats()
|
||||
self.init_toolbar()
|
||||
self.init_context_menus()
|
||||
|
||||
# XXX: Help docs useless/out of date
|
||||
self.window.get_widget("menu_help").hide()
|
||||
|
@ -223,6 +229,38 @@ class vmmManager(vmmGObjectUI):
|
|||
self.engine.decrement_window_counter()
|
||||
return 1
|
||||
|
||||
|
||||
def cleanup(self):
|
||||
self.close()
|
||||
|
||||
try:
|
||||
self.engine = None
|
||||
self.rows = None
|
||||
|
||||
self.diskcol = None
|
||||
self.cpucol = None
|
||||
self.netcol = None
|
||||
|
||||
if self.delete_dialog:
|
||||
self.delete_dialog.cleanup()
|
||||
self.delete_dialog = None
|
||||
|
||||
self.vmmenu.destroy()
|
||||
self.vmmenu = None
|
||||
self.vmmenu_items = None
|
||||
self.vmmenushutdown.destroy()
|
||||
self.vmmenushutdown = None
|
||||
self.vmmenushutdown_items = None
|
||||
self.connmenu.destroy()
|
||||
self.connmenu = None
|
||||
self.connmenu_items = None
|
||||
|
||||
except:
|
||||
logging.exception("Error cleaning up manager")
|
||||
|
||||
vmmGObjectUI.cleanup(self)
|
||||
|
||||
|
||||
def is_visible(self):
|
||||
return bool(self.topwin.flags() & gtk.VISIBLE)
|
||||
|
||||
|
@ -235,19 +273,25 @@ class vmmManager(vmmGObjectUI):
|
|||
################
|
||||
|
||||
def init_stats(self):
|
||||
self.config.on_vmlist_cpu_usage_visible_changed(
|
||||
self.toggle_cpu_usage_visible_widget)
|
||||
self.config.on_vmlist_disk_io_visible_changed(
|
||||
self.toggle_disk_io_visible_widget)
|
||||
self.config.on_vmlist_network_traffic_visible_changed(
|
||||
self.toggle_network_traffic_visible_widget)
|
||||
self.add_gconf_handle(
|
||||
self.config.on_vmlist_cpu_usage_visible_changed(
|
||||
self.toggle_cpu_usage_visible_widget))
|
||||
self.add_gconf_handle(
|
||||
self.config.on_vmlist_disk_io_visible_changed(
|
||||
self.toggle_disk_io_visible_widget))
|
||||
self.add_gconf_handle(
|
||||
self.config.on_vmlist_network_traffic_visible_changed(
|
||||
self.toggle_network_traffic_visible_widget))
|
||||
|
||||
# Register callbacks with the global stats enable/disable values
|
||||
# that disable the associated vmlist widgets if reporting is disabled
|
||||
self.config.on_stats_enable_disk_poll_changed(self.enable_polling,
|
||||
cfg.STATS_DISK)
|
||||
self.config.on_stats_enable_net_poll_changed(self.enable_polling,
|
||||
cfg.STATS_NETWORK)
|
||||
self.add_gconf_handle(
|
||||
self.config.on_stats_enable_disk_poll_changed(self.enable_polling,
|
||||
cfg.STATS_DISK))
|
||||
self.add_gconf_handle(
|
||||
self.config.on_stats_enable_net_poll_changed(self.enable_polling,
|
||||
cfg.STATS_NETWORK))
|
||||
|
||||
|
||||
self.window.get_widget("menu_view_stats_cpu").set_active(
|
||||
self.config.is_vmlist_cpu_usage_visible())
|
||||
|
@ -441,6 +485,9 @@ class vmmManager(vmmGObjectUI):
|
|||
|
||||
model.set_sort_column_id(COL_NAME, gtk.SORT_ASCENDING)
|
||||
|
||||
self.diskcol = diskIOCol
|
||||
self.netcol = networkTrafficCol
|
||||
self.cpucol = cpuUsageCol
|
||||
|
||||
##################
|
||||
# Helper methods #
|
||||
|
@ -1090,19 +1137,14 @@ class vmmManager(vmmGObjectUI):
|
|||
widget.set_label(current_text)
|
||||
|
||||
def toggle_network_traffic_visible_widget(self, *ignore):
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
col = vmlist.get_column(COL_NETWORK)
|
||||
col.set_visible(self.config.is_vmlist_network_traffic_visible())
|
||||
self.netcol.set_visible(
|
||||
self.config.is_vmlist_network_traffic_visible())
|
||||
|
||||
def toggle_disk_io_visible_widget(self, *ignore):
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
col = vmlist.get_column(COL_DISK)
|
||||
col.set_visible(self.config.is_vmlist_disk_io_visible())
|
||||
self.diskcol.set_visible(self.config.is_vmlist_disk_io_visible())
|
||||
|
||||
def toggle_cpu_usage_visible_widget(self, *ignore):
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
col = vmlist.get_column(COL_CPU)
|
||||
col.set_visible(self.config.is_vmlist_cpu_usage_visible())
|
||||
self.cpucol.set_visible(self.config.is_vmlist_cpu_usage_visible())
|
||||
|
||||
def toggle_stats_visible(self, src, stats_id):
|
||||
visible = src.get_active()
|
||||
|
|
|
@ -91,6 +91,19 @@ class vmmMigrateDialog(vmmGObjectUI):
|
|||
self.topwin.hide()
|
||||
return 1
|
||||
|
||||
def cleanup(self):
|
||||
self.close()
|
||||
|
||||
self.vm = None
|
||||
self.conn = None
|
||||
self.engine = None
|
||||
self.destconn_rows = None
|
||||
|
||||
# Not sure why we need to do this manually, but it matters
|
||||
self.window.get_widget("migrate-dest").get_model().clear()
|
||||
|
||||
vmmGObjectUI.cleanup(self)
|
||||
|
||||
def init_state(self):
|
||||
# [hostname, conn, can_migrate, tooltip]
|
||||
dest_model = gtk.ListStore(str, object, bool, str)
|
||||
|
|
|
@ -35,23 +35,23 @@ class vmmPreferences(vmmGObjectUI):
|
|||
def __init__(self):
|
||||
vmmGObjectUI.__init__(self, "vmm-preferences.glade", "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_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)
|
||||
self.config.on_sound_local_changed(self.refresh_sound_local)
|
||||
self.config.on_sound_remote_changed(self.refresh_sound_remote)
|
||||
self.config.on_graphics_type_changed(self.refresh_graphics_type)
|
||||
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.add_gconf_handle(self.config.on_view_system_tray_changed(self.refresh_view_system_tray))
|
||||
self.add_gconf_handle(self.config.on_console_popup_changed(self.refresh_console_popup))
|
||||
self.add_gconf_handle(self.config.on_console_accels_changed(self.refresh_console_accels))
|
||||
self.add_gconf_handle(self.config.on_console_scaling_changed(self.refresh_console_scaling))
|
||||
self.add_gconf_handle(self.config.on_stats_update_interval_changed(self.refresh_update_interval))
|
||||
self.add_gconf_handle(self.config.on_stats_history_length_changed(self.refresh_history_length))
|
||||
self.add_gconf_handle(self.config.on_sound_local_changed(self.refresh_sound_local))
|
||||
self.add_gconf_handle(self.config.on_sound_remote_changed(self.refresh_sound_remote))
|
||||
self.add_gconf_handle(self.config.on_graphics_type_changed(self.refresh_graphics_type))
|
||||
self.add_gconf_handle(self.config.on_stats_enable_disk_poll_changed(self.refresh_disk_poll))
|
||||
self.add_gconf_handle(self.config.on_stats_enable_net_poll_changed(self.refresh_net_poll))
|
||||
|
||||
self.config.on_confirm_forcepoweroff_changed(self.refresh_confirm_forcepoweroff)
|
||||
self.config.on_confirm_poweroff_changed(self.refresh_confirm_poweroff)
|
||||
self.config.on_confirm_pause_changed(self.refresh_confirm_pause)
|
||||
self.config.on_confirm_removedev_changed(self.refresh_confirm_removedev)
|
||||
self.config.on_confirm_interface_changed(self.refresh_confirm_interface)
|
||||
self.add_gconf_handle(self.config.on_confirm_forcepoweroff_changed(self.refresh_confirm_forcepoweroff))
|
||||
self.add_gconf_handle(self.config.on_confirm_poweroff_changed(self.refresh_confirm_poweroff))
|
||||
self.add_gconf_handle(self.config.on_confirm_pause_changed(self.refresh_confirm_pause))
|
||||
self.add_gconf_handle(self.config.on_confirm_removedev_changed(self.refresh_confirm_removedev))
|
||||
self.add_gconf_handle(self.config.on_confirm_interface_changed(self.refresh_confirm_interface))
|
||||
|
||||
self.refresh_view_system_tray()
|
||||
self.refresh_update_interval()
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
# MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
import logging
|
||||
|
||||
import gobject
|
||||
import gtk
|
||||
|
||||
|
@ -90,7 +92,9 @@ class vmmSystray(vmmGObject):
|
|||
|
||||
self.init_systray_menu()
|
||||
|
||||
self.config.on_view_system_tray_changed(self.show_systray)
|
||||
self.add_gconf_handle(
|
||||
self.config.on_view_system_tray_changed(self.show_systray))
|
||||
|
||||
self.show_systray()
|
||||
|
||||
def is_visible(self):
|
||||
|
@ -102,6 +106,20 @@ class vmmSystray(vmmGObject):
|
|||
self.systray_icon and
|
||||
self.systray_icon.is_embedded())
|
||||
|
||||
def cleanup(self):
|
||||
vmmGObject.cleanup(self)
|
||||
|
||||
try:
|
||||
self.err = None
|
||||
|
||||
if self.systray_menu:
|
||||
self.systray_menu.destroy()
|
||||
self.systray_menu = None
|
||||
|
||||
self.systray_icon = None
|
||||
except:
|
||||
logging.exception("Error cleaning up systray")
|
||||
|
||||
# Initialization routines
|
||||
|
||||
def init_systray_menu(self):
|
||||
|
|
|
@ -50,6 +50,10 @@ def set_error_parent(parent):
|
|||
err_dial.set_parent(parent)
|
||||
err_dial = err_dial
|
||||
|
||||
def cleanup():
|
||||
global err_dial
|
||||
err_dial = None
|
||||
|
||||
############################################################
|
||||
# Helpers for shared storage UI between create/addhardware #
|
||||
############################################################
|
||||
|
|
Loading…
Reference in New Issue