console: Support spice 'resize-guest' (bz 754559)
This will auto change the guest resolution to match the window size. Off by default, can be enabled like scaling preferences.
This commit is contained in:
parent
382543e15f
commit
bff94f2365
|
@ -19,6 +19,12 @@
|
|||
<summary>Username and secrets ID for graphical password</summary>
|
||||
<description>Username and secrets ID for graphical password</description>
|
||||
</key>
|
||||
|
||||
<key name="resize-guest" type="i">
|
||||
<default>-1</default>
|
||||
<summary>Automatically resize guest when window size changes</summary>
|
||||
<description>Automatically change guest resolution along with virt-manager window. Only works with spice with a vdagent set up. -1 = global default, 0 = off, 1 = on.</description>
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
<schema id="org.virt-manager.virt-manager"
|
||||
|
@ -166,6 +172,12 @@
|
|||
<description>When to scale the VM graphical console. 0 = never, 1 = only when in full screen mode, 2 = Always</description>
|
||||
</key>
|
||||
|
||||
<key name="resize-guest" type="i">
|
||||
<default>-1</default>
|
||||
<summary>Automatically resize guest when window size changes</summary>
|
||||
<description>Automatically change guest resolution along with virt-manager window. Only works with spice with a vdagent set up. -1 = global default, 0 = off, 1 = on.</description>
|
||||
</key>
|
||||
|
||||
<key name="grab-keys" type="s">
|
||||
<default>''</default>
|
||||
<summary>Grab keyboard sequence for the graphical console</summary>
|
||||
|
|
|
@ -301,6 +301,21 @@
|
|||
<signal name="toggled" handler="on_details_menu_view_scale_never_toggled" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="menuitem3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckMenuItem" id="details-menu-view-resizeguest">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Auto _resize VM with window</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="toggled" handler="on_details_menu_view_resizeguest_toggled" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -1,18 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.16.0 on Fri Jan 17 17:40:39 2014 -->
|
||||
<!-- Generated with glade 3.16.1 -->
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<requires lib="gtk+" version="3.0"/>
|
||||
<object class="GtkAdjustment" id="adjustment1">
|
||||
<property name="lower">1</property>
|
||||
<property name="upper">60</property>
|
||||
<property name="step_increment">1</property>
|
||||
<property name="page_increment">5</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="adjustment2">
|
||||
<property name="upper">300</property>
|
||||
<property name="step_increment">5</property>
|
||||
<property name="page_increment">5</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="vmm-preferences">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="border_width">12</property>
|
||||
|
@ -542,7 +537,7 @@ identical CPUs in order to migrate the VM.</property>
|
|||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
|
@ -572,7 +567,7 @@ identical CPUs in order to migrate the VM.</property>
|
|||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
|
@ -589,7 +584,7 @@ identical CPUs in order to migrate the VM.</property>
|
|||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
|
@ -604,6 +599,37 @@ identical CPUs in order to migrate the VM.</property>
|
|||
<property name="hexpand">False</property>
|
||||
<signal name="clicked" handler="on_prefs_btn_keys_define_clicked" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label26">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Change guest resolution when the guest window size is changed. Only works with properly configured guest using spice and the desktop agent.</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Resize guest with window:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">prefs-console-resizeguest</property>
|
||||
<property name="lines">2</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="width">1</property>
|
||||
<property name="height">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="prefs-console-resizeguest">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<signal name="changed" handler="on_prefs_console_resizeguest_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
|
@ -946,4 +972,9 @@ identical CPUs in order to migrate the VM.</property>
|
|||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="adjustment2">
|
||||
<property name="upper">300</property>
|
||||
<property name="step_increment">5</property>
|
||||
<property name="page_increment">5</property>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
|
@ -135,10 +135,6 @@ class vmmConfig(object):
|
|||
CONSOLE_SCALE_FULLSCREEN = 1
|
||||
CONSOLE_SCALE_ALWAYS = 2
|
||||
|
||||
_PEROBJ_FUNC_SET = 0
|
||||
_PEROBJ_FUNC_GET = 1
|
||||
_PEROBJ_FUNC_LISTEN = 2
|
||||
|
||||
DEFAULT_XEN_IMAGE_DIR = "/var/lib/xen/images"
|
||||
DEFAULT_XEN_SAVE_DIR = "/var/lib/xen/dump"
|
||||
|
||||
|
@ -166,8 +162,10 @@ class vmmConfig(object):
|
|||
self.libvirt_packages = cliconfig.libvirt_packages
|
||||
self.askpass_package = cliconfig.askpass_package
|
||||
self.default_graphics_from_config = cliconfig.default_graphics
|
||||
|
||||
self.default_storage_format_from_config = "qcow2"
|
||||
self.cpu_default_from_config = "host-cpu-model"
|
||||
self.default_console_resizeguest = 0
|
||||
|
||||
self._objects = []
|
||||
|
||||
|
@ -381,6 +379,16 @@ class vmmConfig(object):
|
|||
def set_console_scaling(self, pref):
|
||||
self.conf.set("/console/scaling", pref)
|
||||
|
||||
def on_console_resizeguest_changed(self, cb):
|
||||
return self.conf.notify_add("/console/resize-guest", cb)
|
||||
def get_console_resizeguest(self):
|
||||
val = self.conf.get("/console/resize-guest")
|
||||
if val == -1:
|
||||
val = self.default_console_resizeguest
|
||||
return val
|
||||
def set_console_resizeguest(self, pref):
|
||||
self.conf.set("/console/resize-guest", pref)
|
||||
|
||||
def get_auto_redirection(self):
|
||||
return self.conf.get("/console/auto-redirect")
|
||||
def set_auto_redirection(self, state):
|
||||
|
|
|
@ -371,9 +371,15 @@ class Viewer(vmmGObject):
|
|||
|
||||
def has_usb_redirection(self):
|
||||
return False
|
||||
def has_agent(self):
|
||||
return False
|
||||
def set_resizeguest(self, val):
|
||||
ignore = val
|
||||
|
||||
|
||||
class VNCViewer(Viewer):
|
||||
viewer_type = "vnc"
|
||||
|
||||
def __init__(self, console):
|
||||
Viewer.__init__(self, console)
|
||||
self.display = GtkVnc.Display.new()
|
||||
|
@ -393,6 +399,7 @@ class VNCViewer(Viewer):
|
|||
self.display.set_force_size(False)
|
||||
|
||||
self.console.sync_scaling_with_display()
|
||||
self.console.refresh_resizeguest_from_settings()
|
||||
|
||||
self.display.set_keyboard_grab(True)
|
||||
self.display.set_pointer_grab(True)
|
||||
|
@ -549,17 +556,21 @@ class VNCViewer(Viewer):
|
|||
|
||||
|
||||
class SpiceViewer(Viewer):
|
||||
viewer_type = "spice"
|
||||
|
||||
def __init__(self, console):
|
||||
Viewer.__init__(self, console)
|
||||
self.spice_session = None
|
||||
self.display = None
|
||||
self.audio = None
|
||||
self.main_channel = None
|
||||
self.display_channel = None
|
||||
self.usbdev_manager = None
|
||||
|
||||
def _init_widget(self):
|
||||
self.set_grab_keys()
|
||||
self.console.sync_scaling_with_display()
|
||||
self.console.refresh_resizeguest_from_settings()
|
||||
|
||||
self.display.realize()
|
||||
|
||||
|
@ -613,6 +624,7 @@ class SpiceViewer(Viewer):
|
|||
self.display.destroy()
|
||||
self.display = None
|
||||
self.display_channel = None
|
||||
self.main_channel = None
|
||||
self.usbdev_manager = None
|
||||
|
||||
def is_open(self):
|
||||
|
@ -653,13 +665,17 @@ class SpiceViewer(Viewer):
|
|||
GObject.GObject.connect(channel, "open-fd",
|
||||
self._channel_open_fd_request)
|
||||
|
||||
if type(channel) == SpiceClientGLib.MainChannel:
|
||||
if (type(channel) == SpiceClientGLib.MainChannel and
|
||||
not self.main_channel):
|
||||
if self.console.tunnels:
|
||||
self.console.tunnels.unlock()
|
||||
channel.connect_after("channel-event", self._main_channel_event_cb)
|
||||
return
|
||||
self.main_channel = channel
|
||||
self.main_channel.connect_after("channel-event",
|
||||
self._main_channel_event_cb)
|
||||
self.main_channel.connect_after("notify::agent-connected",
|
||||
self._agent_connected_cb)
|
||||
|
||||
if (type(channel) == SpiceClientGLib.DisplayChannel and
|
||||
elif (type(channel) == SpiceClientGLib.DisplayChannel and
|
||||
not self.display):
|
||||
channel_id = channel.get_property("channel-id")
|
||||
|
||||
|
@ -673,13 +689,11 @@ class SpiceViewer(Viewer):
|
|||
self.console.widget("console-gfx-viewport").add(self.display)
|
||||
self._init_widget()
|
||||
self.console.connected()
|
||||
return
|
||||
|
||||
if (type(channel) in [SpiceClientGLib.PlaybackChannel,
|
||||
SpiceClientGLib.RecordChannel] and
|
||||
elif (type(channel) in [SpiceClientGLib.PlaybackChannel,
|
||||
SpiceClientGLib.RecordChannel] and
|
||||
not self.audio):
|
||||
self.audio = SpiceClientGLib.Audio.get(self.spice_session, None)
|
||||
return
|
||||
|
||||
def get_desktop_resolution(self):
|
||||
if (not self.display_channel or
|
||||
|
@ -687,6 +701,16 @@ class SpiceViewer(Viewer):
|
|||
return None
|
||||
return self.display_channel.get_properties("width", "height")
|
||||
|
||||
def has_agent(self):
|
||||
if (not self.main_channel or
|
||||
not has_property(self.main_channel, "agent-connected")):
|
||||
return False
|
||||
ret = self.main_channel.get_property("agent-connected")
|
||||
return ret
|
||||
|
||||
def _agent_connected_cb(self, src, val):
|
||||
self.console.refresh_resizeguest_from_settings()
|
||||
|
||||
def _create_spice_session(self):
|
||||
self.spice_session = SpiceClientGLib.Session()
|
||||
SpiceClientGLib.set_session_option(self.spice_session)
|
||||
|
@ -742,6 +766,10 @@ class SpiceViewer(Viewer):
|
|||
return
|
||||
self.display.set_property("scaling", scaling)
|
||||
|
||||
def set_resizeguest(self, val):
|
||||
if self.display:
|
||||
self.display.set_property("resize-guest", val)
|
||||
|
||||
def _usbdev_redirect_error(self,
|
||||
spice_usbdev_widget, spice_usb_device,
|
||||
errstr):
|
||||
|
@ -829,6 +857,10 @@ class vmmConsolePages(vmmGObjectUI):
|
|||
self.add_gconf_handle(
|
||||
self.vm.on_console_scaling_changed(
|
||||
self.refresh_scaling_from_settings))
|
||||
self.refresh_resizeguest_from_settings()
|
||||
self.add_gconf_handle(
|
||||
self.vm.on_console_resizeguest_changed(
|
||||
self.refresh_resizeguest_from_settings))
|
||||
|
||||
scroll = self.widget("console-gfx-scroll")
|
||||
scroll.connect("size-allocate", self.scroll_size_allocate)
|
||||
|
@ -1032,6 +1064,42 @@ class vmmConsolePages(vmmGObjectUI):
|
|||
# Make sure modifiers are up to date
|
||||
self.viewer_focus_changed()
|
||||
|
||||
def refresh_resizeguest_from_settings(self):
|
||||
tooltip = ""
|
||||
if self.viewer:
|
||||
if self.viewer.viewer_type != "spice":
|
||||
tooltip = (
|
||||
_("Graphics type '%s' does not support auto resize.") %
|
||||
self.viewer.viewer_type)
|
||||
elif not self.viewer.has_agent():
|
||||
tooltip = _("Guest agent is not available.")
|
||||
|
||||
val = self.vm.get_console_resizeguest()
|
||||
widget = self.widget("details-menu-view-resizeguest")
|
||||
widget.set_tooltip_text(tooltip)
|
||||
widget.set_sensitive(not bool(tooltip))
|
||||
if not tooltip:
|
||||
self.widget("details-menu-view-resizeguest").set_active(bool(val))
|
||||
|
||||
self.sync_resizeguest_with_display()
|
||||
|
||||
def resizeguest_ui_changed_cb(self, src):
|
||||
# Called from details.py
|
||||
if not src.get_active():
|
||||
return
|
||||
|
||||
val = int(self.widget("details-menu-view-resizeguest").get_active())
|
||||
self.vm.set_console_resizeguest(val)
|
||||
self.sync_resizeguest_with_display()
|
||||
|
||||
def sync_resizeguest_with_display(self):
|
||||
if not self.viewer:
|
||||
return
|
||||
|
||||
val = bool(self.vm.get_console_resizeguest())
|
||||
self.viewer.set_resizeguest(val)
|
||||
self.widget("console-gfx-scroll").queue_resize()
|
||||
|
||||
def refresh_scaling_from_settings(self):
|
||||
scale_type = self.vm.get_console_scaling()
|
||||
self.widget("details-menu-view-scale-always").set_active(
|
||||
|
@ -1287,6 +1355,7 @@ class vmmConsolePages(vmmGObjectUI):
|
|||
error += "\n\nError: %s" % errout
|
||||
|
||||
self.activate_unavailable_page(error)
|
||||
self.refresh_resizeguest_from_settings()
|
||||
|
||||
def _set_viewer_connected(self, val):
|
||||
self._viewer_connected = val
|
||||
|
|
|
@ -547,6 +547,7 @@ class vmmDetails(vmmGObjectUI):
|
|||
"on_details_menu_view_scale_always_toggled": self.console.scaling_ui_changed_cb,
|
||||
"on_details_menu_view_scale_fullscreen_toggled": self.console.scaling_ui_changed_cb,
|
||||
"on_details_menu_view_scale_never_toggled": self.console.scaling_ui_changed_cb,
|
||||
"on_details_menu_view_resizeguest_toggled": self.console.resizeguest_ui_changed_cb,
|
||||
|
||||
"on_console_pages_switch_page": self.console.page_changed,
|
||||
"on_console_auth_password_activate": self.console.auth_login,
|
||||
|
|
|
@ -1627,6 +1627,17 @@ class vmmDomain(vmmLibvirtObject):
|
|||
return self.config.get_console_scaling()
|
||||
return ret
|
||||
|
||||
def on_console_resizeguest_changed(self, *args, **kwargs):
|
||||
return self.config.listen_pervm(self.uuid, "/resize-guest",
|
||||
*args, **kwargs)
|
||||
def set_console_resizeguest(self, value):
|
||||
self.config.set_pervm(self.uuid, "/resize-guest", value)
|
||||
def get_console_resizeguest(self):
|
||||
ret = self.config.get_pervm(self.uuid, "/resize-guest")
|
||||
if ret == -1:
|
||||
return self.config.get_console_resizeguest()
|
||||
return ret
|
||||
|
||||
def set_details_window_size(self, w, h):
|
||||
self.config.set_pervm(self.uuid, "/vm-window-size", (w, h))
|
||||
def get_details_window_size(self):
|
||||
|
|
|
@ -39,6 +39,7 @@ class vmmPreferences(vmmGObjectUI):
|
|||
self.refresh_update_interval()
|
||||
self.refresh_console_accels()
|
||||
self.refresh_console_scaling()
|
||||
self.refresh_console_resizeguest()
|
||||
self.refresh_new_vm_sound()
|
||||
self.refresh_graphics_type()
|
||||
self.refresh_storage_format()
|
||||
|
@ -60,6 +61,7 @@ class vmmPreferences(vmmGObjectUI):
|
|||
"on_prefs_stats_update_interval_changed": self.change_update_interval,
|
||||
"on_prefs_console_accels_toggled": self.change_console_accels,
|
||||
"on_prefs_console_scaling_changed": self.change_console_scaling,
|
||||
"on_prefs_console_resizeguest_changed": self.change_console_resizeguest,
|
||||
"on_prefs_close_clicked": self.close,
|
||||
"on_vmm_preferences_delete_event": self.close,
|
||||
"on_prefs_new_vm_sound_toggled": self.change_new_vm_sound,
|
||||
|
@ -104,6 +106,20 @@ class vmmPreferences(vmmGObjectUI):
|
|||
combo.set_model(model)
|
||||
uiutil.set_combo_text_column(combo, 1)
|
||||
|
||||
combo = self.widget("prefs-console-resizeguest")
|
||||
# [gsettings value, string]
|
||||
model = Gtk.ListStore(int, str)
|
||||
vals = {
|
||||
0: _("Off"),
|
||||
1: _("On"),
|
||||
}
|
||||
model.append([-1, _("System default (%s)") %
|
||||
vals[self.config.default_console_resizeguest]])
|
||||
for key, val in vals.items():
|
||||
model.append([key, val])
|
||||
combo.set_model(model)
|
||||
uiutil.set_combo_text_column(combo, 1)
|
||||
|
||||
combo = self.widget("prefs-graphics-type")
|
||||
# [gsettings value, string]
|
||||
model = Gtk.ListStore(str, str)
|
||||
|
@ -157,6 +173,10 @@ class vmmPreferences(vmmGObjectUI):
|
|||
combo = self.widget("prefs-console-scaling")
|
||||
val = self.config.get_console_scaling()
|
||||
uiutil.set_row_selection(combo, val)
|
||||
def refresh_console_resizeguest(self):
|
||||
combo = self.widget("prefs-console-resizeguest")
|
||||
val = self.config.get_console_resizeguest()
|
||||
uiutil.set_row_selection(combo, val)
|
||||
|
||||
def refresh_new_vm_sound(self):
|
||||
self.widget("prefs-new-vm-sound").set_active(
|
||||
|
@ -294,6 +314,9 @@ class vmmPreferences(vmmGObjectUI):
|
|||
self.config.set_console_accels(src.get_active())
|
||||
def change_console_scaling(self, box):
|
||||
self.config.set_console_scaling(box.get_active())
|
||||
def change_console_resizeguest(self, box):
|
||||
val = uiutil.get_list_selection(box, 0)
|
||||
self.config.set_console_resizeguest(val)
|
||||
|
||||
def change_new_vm_sound(self, src):
|
||||
self.config.set_new_vm_sound(src.get_active())
|
||||
|
|
|
@ -103,7 +103,7 @@ def set_row_selection(listwidget, prevkey):
|
|||
"""
|
||||
model = listwidget.get_model()
|
||||
_iter = None
|
||||
if prevkey:
|
||||
if prevkey is not None:
|
||||
for row in model:
|
||||
if row[0] == prevkey:
|
||||
_iter = row.iter
|
||||
|
|
Loading…
Reference in New Issue