From 7c23a46f497757994503bc00172de83d7a1c37fd Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Wed, 10 Mar 2021 07:34:18 +0100 Subject: [PATCH 1/2] virt-manager: move window resizing from details/console to vmwindow This is in preparation for a more involved UI logic change where the size of the window needs to be decoupled from the "full-screen" mode of the console. Signed-off-by: Balazs Scheidler --- virtManager/details/console.py | 2 -- virtManager/vmwindow.py | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/virtManager/details/console.py b/virtManager/details/console.py index 18f9ddd91..80d015d50 100644 --- a/virtManager/details/console.py +++ b/virtManager/details/console.py @@ -556,12 +556,10 @@ def _leave_fullscreen(self, ignore=None): def _change_fullscreen(self, do_fullscreen): if do_fullscreen: self._in_fullscreen = True - self.topwin.fullscreen() self._overlay_toolbar_fullscreen.timed_revealer.force_reveal(True) else: self._in_fullscreen = False self._overlay_toolbar_fullscreen.timed_revealer.force_reveal(False) - self.topwin.unfullscreen() self._sync_scaling_with_display() diff --git a/virtManager/vmwindow.py b/virtManager/vmwindow.py index 7783ead4e..2c2bdf35b 100644 --- a/virtManager/vmwindow.py +++ b/virtManager/vmwindow.py @@ -650,6 +650,12 @@ def _scaling_ui_changed_cb(self, src): def _fullscreen_changed_cb(self, src): do_fullscreen = src.get_active() self.widget("control-fullscreen").set_active(do_fullscreen) + + if do_fullscreen: + self.topwin.fullscreen() + else: + self.topwin.unfullscreen() + self._console.vmwindow_set_fullscreen(do_fullscreen) self.widget("details-menubar").set_visible(not do_fullscreen) From e4f35dbb22972b8be63fb0034cba1065bee3e308 Mon Sep 17 00:00:00 2001 From: Balazs Scheidler Date: Wed, 10 Mar 2021 07:37:49 +0100 Subject: [PATCH 2/2] virt-manager: implement undecorated window mode I have a 4k monitor and I have a VM that uses 1920x1080 resolution, which I would like to lay out in the top-right corner of my monitor. The problem is that as long as the window decoration, menubar and toolbar is visible, 1920x1080 does not fit in the 1/4th of my monitor. Also, the current virtual VGA driver for Windows does not support non-standard resolutions like VirtualBox, thus I am either seeing a lot of "black" space around my virtual desktop, or I would have to increase the size of my virt-manager window. None of this is appealing, so this patch implements a "windowed" full screen mode, which is basically an undecorated window, without a menu or toolbar. The same overlay is available at the top of the window than what is available in full screen. Signed-off-by: Balazs Scheidler --- ui/vmwindow.ui | 15 ++++++++ virtManager/vmwindow.py | 79 ++++++++++++++++++++++++++++++++++------- 2 files changed, 81 insertions(+), 13 deletions(-) diff --git a/ui/vmwindow.ui b/ui/vmwindow.ui index 44afa55c7..db052a599 100644 --- a/ui/vmwindow.ui +++ b/ui/vmwindow.ui @@ -182,6 +182,21 @@ + + + True + False + Display in _Undecorated Window + True + + + + + + True + False + + True diff --git a/virtManager/vmwindow.py b/virtManager/vmwindow.py index 2c2bdf35b..31e1d893e 100644 --- a/virtManager/vmwindow.py +++ b/virtManager/vmwindow.py @@ -22,6 +22,9 @@ DETAILS_PAGE_CONSOLE, DETAILS_PAGE_SNAPSHOTS) = range(3) +(CONSOLE_DISPLAY_WINDOWED, + CONSOLE_DISPLAY_UNDECORATED_WINDOW, + CONSOLE_DISPLAY_FULLSCREEN) = range(3) class vmmVMWindow(vmmGObjectUI): __gsignals__ = { @@ -93,6 +96,7 @@ def __init__(self, vm, parent=None): self._shutdownmenu = None self._vmmenu = None + self._console_display_mode = CONSOLE_DISPLAY_WINDOWED self.init_menus() self.builder.connect_signals({ @@ -108,7 +112,7 @@ def __init__(self, vm, parent=None): "on_control_run_clicked": self.control_vm_run, "on_control_shutdown_clicked": self.control_vm_shutdown, "on_control_pause_toggled": self.control_vm_pause, - "on_control_fullscreen_toggled": self.control_fullscreen, + "on_control_fullscreen_toggled": self._toolbar_fullscreen_changed_cb, "on_details_customize_finish_clicked": self.customize_finish, "on_details_cancel_customize_clicked": self._customize_cancel_clicked, @@ -125,6 +129,7 @@ def __init__(self, vm, parent=None): "on_details_pages_switch_page": self._details_page_switch_cb, "on_details_menu_view_fullscreen_activate": self._fullscreen_changed_cb, + "on_details_menu_view_undecorated_window_activate": self._undecorated_window_changed_cb, "on_details_menu_view_size_to_vm_activate": self._size_to_vm_cb, "on_details_menu_view_scale_always_toggled": self._scaling_ui_changed_cb, "on_details_menu_view_scale_fullscreen_toggled": self._scaling_ui_changed_cb, @@ -301,10 +306,6 @@ def window_resized(self, ignore, ignore2): return # pragma: no cover self._window_size = self.topwin.get_size() - def control_fullscreen(self, src): - menu = self.widget("details-menu-view-fullscreen") - if src.get_active() != menu.get_active(): - menu.set_active(src.get_active()) def toggle_toolbar(self, src): if self.is_customize_dialog: @@ -312,7 +313,7 @@ def toggle_toolbar(self, src): active = src.get_active() self.config.set_details_show_toolbar(active) - fsactive = self.widget("details-menu-view-fullscreen").get_active() + fsactive = self.widget("details-menu-view-fullscreen").get_active() or self.widget("details-menu-view-undecorated-window").get_active() self.widget("toolbar-box").set_visible(active and not fsactive) def details_console_changed(self, src): @@ -620,6 +621,8 @@ def _console_refresh_can_fullscreen(self): self.widget("control-fullscreen").set_sensitive(allow_fullscreen) self.widget("details-menu-view-fullscreen").set_sensitive( allow_fullscreen) + self.widget("details-menu-view-undecorated-window").set_sensitive( + allow_fullscreen) def _console_refresh_scaling_from_settings(self): scale_type = self.vm.get_console_scaling() @@ -647,23 +650,73 @@ def _scaling_ui_changed_cb(self, src): self.vm.set_console_scaling(scale_type) + def _toolbar_fullscreen_changed_cb(self, src): + if src.get_active(): + + if self._console_display_mode == CONSOLE_DISPLAY_WINDOWED: + # toggled in the toolbar, we switch to full screen mode by + # activating the "fullscreen" menu item + + self.widget('details-menu-view-undecorated-window').set_active(False) + self.widget('details-menu-view-fullscreen').set_active(True) + else: + # the toolbar button was activated in fullscreen/undecorated + # window mode, no need to do anything + pass + else: + + if self._console_display_mode != CONSOLE_DISPLAY_WINDOWED: + # we left full-screen mode because of the "overlaid" exit + # button, which deactivates the toolbar button, let's deactivate + # the related menu elements as well. + + self.widget('details-menu-view-undecorated-window').set_active(False) + self.widget('details-menu-view-fullscreen').set_active(False) + else: + # the toolbar button cannot be deactivated in windowed mode + # (as it is not visible), unless programatically, let's not do anything + pass + def _fullscreen_changed_cb(self, src): - do_fullscreen = src.get_active() - self.widget("control-fullscreen").set_active(do_fullscreen) + if src.get_active(): + self._toggle_display_mode(CONSOLE_DISPLAY_FULLSCREEN) + else: + self._toggle_display_mode(CONSOLE_DISPLAY_WINDOWED) - if do_fullscreen: - self.topwin.fullscreen() + def _undecorated_window_changed_cb(self, src): + if src.get_active(): + self._toggle_display_mode(CONSOLE_DISPLAY_UNDECORATED_WINDOW) else: + self._toggle_display_mode(CONSOLE_DISPLAY_WINDOWED) + + def _toggle_display_mode(self, mode): + print("toggle_display_mode", mode, 'previous mode', self._console_display_mode) + + if self._console_display_mode == mode: + return + decoration_needed = (mode == CONSOLE_DISPLAY_WINDOWED) + console_in_fullscreen = (mode != CONSOLE_DISPLAY_WINDOWED) + + + if mode == CONSOLE_DISPLAY_FULLSCREEN: + self.topwin.fullscreen() + elif mode == CONSOLE_DISPLAY_WINDOWED: self.topwin.unfullscreen() + self.topwin.set_decorated(True) + elif mode == CONSOLE_DISPLAY_UNDECORATED_WINDOW: + self.topwin.set_decorated(False) - self._console.vmwindow_set_fullscreen(do_fullscreen) + self._console.vmwindow_set_fullscreen(console_in_fullscreen) - self.widget("details-menubar").set_visible(not do_fullscreen) + self.widget("details-menubar").set_visible(decoration_needed) - show_toolbar = not do_fullscreen + show_toolbar = decoration_needed if not self.widget("details-menu-view-toolbar").get_active(): show_toolbar = False # pragma: no cover self.widget("toolbar-box").set_visible(show_toolbar) + self._console_display_mode = mode + self.widget("control-fullscreen").set_active(console_in_fullscreen) + def _resizeguest_ui_changed_cb(self, src): if not src.get_sensitive():