diff mbox series

[2/3] ui/gtk: detach_all option for making all VCs detached upon starting

Message ID 20220428231304.19472-3-dongwon.kim@intel.com (mailing list archive)
State New, archived
Headers show
Series ui/gtk: new options, monitor and detach-all | expand

Commit Message

Kim, Dongwon April 28, 2022, 11:13 p.m. UTC
With "detach-all=on" for display, QEMU starts with all VC windows
detached automatically.

If used with "full-screen=on", it places individual windows (from
top window) starting from monitor 0 or monitor n in case monitor=n.

In case # mon < # VCs, only same number of VCs as # mon will be sent to
the monitors for full-screen while others are remaining in windowed-mode.

Target monitor number for individual VC is rotated in case monitor=n
(n != 0) (e.g. if monitor=1 and # VCs = 2, the top window will be
full-screened on monitor 1 and top second window will be full-screened
on monitor 0.)

v2: update Since version to 7.1

Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Vivek Kasireddy <vivek.kasireddy@intel.com>
Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
---
 qapi/ui.json |  5 ++++-
 ui/gtk.c     | 47 ++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 48 insertions(+), 4 deletions(-)

Comments

Daniel P. Berrangé May 3, 2022, 9:12 a.m. UTC | #1
On Thu, Apr 28, 2022 at 04:13:03PM -0700, Dongwon Kim wrote:
> With "detach-all=on" for display, QEMU starts with all VC windows
> detached automatically.
> 
> If used with "full-screen=on", it places individual windows (from
> top window) starting from monitor 0 or monitor n in case monitor=n.
> 
> In case # mon < # VCs, only same number of VCs as # mon will be sent to
> the monitors for full-screen while others are remaining in windowed-mode.
> 
> Target monitor number for individual VC is rotated in case monitor=n
> (n != 0) (e.g. if monitor=1 and # VCs = 2, the top window will be
> full-screened on monitor 1 and top second window will be full-screened
> on monitor 0.)

I tend to wonder whether we actually need this at all, as opposed
to just changing QEMU's behaviour by default.

It makes sense to have tabs per-VC for the things like the HMP
console, serial ports, etc, but I think graphical video outputs
should always be displayed as multiple windows. Putting graphical
outputs as tabs rather defeats the purpose of having multiple
outputs IMHO. 

IOW, why won't we just create 1 gtk window per graphical output
all the time.

With regards,
Daniel
Kim, Dongwon May 3, 2022, 11:21 p.m. UTC | #2
On Tue, May 03, 2022 at 10:12:43AM +0100, Daniel P. Berrangé wrote:
> On Thu, Apr 28, 2022 at 04:13:03PM -0700, Dongwon Kim wrote:
> > With "detach-all=on" for display, QEMU starts with all VC windows
> > detached automatically.
> > 
> > If used with "full-screen=on", it places individual windows (from
> > top window) starting from monitor 0 or monitor n in case monitor=n.
> > 
> > In case # mon < # VCs, only same number of VCs as # mon will be sent to
> > the monitors for full-screen while others are remaining in windowed-mode.
> > 
> > Target monitor number for individual VC is rotated in case monitor=n
> > (n != 0) (e.g. if monitor=1 and # VCs = 2, the top window will be
> > full-screened on monitor 1 and top second window will be full-screened
> > on monitor 0.)
> 
> I tend to wonder whether we actually need this at all, as opposed
> to just changing QEMU's behaviour by default.
> 
> It makes sense to have tabs per-VC for the things like the HMP
> console, serial ports, etc, but I think graphical video outputs
> should always be displayed as multiple windows. Putting graphical
> outputs as tabs rather defeats the purpose of having multiple
> outputs IMHO. 
> 
> IOW, why won't we just create 1 gtk window per graphical output
> all the time.

I got your point but I think this requires changes in the
policy, which I guess need community-wide agreement. Why don't we move
on with this new option and at the same time start the discussion?

One more point is, I tried to find out but I couldn't think of any good way
to distinguish between guest output consoles and other consoles. Do you
have any thought on this?

> 
> With regards,
> Daniel
> -- 
> |: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org         -o-            https://fstop138.berrange.com :|
> |: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
>
Daniel P. Berrangé May 4, 2022, 8:28 a.m. UTC | #3
On Tue, May 03, 2022 at 04:21:44PM -0700, Dongwon Kim wrote:
> On Tue, May 03, 2022 at 10:12:43AM +0100, Daniel P. Berrangé wrote:
> > On Thu, Apr 28, 2022 at 04:13:03PM -0700, Dongwon Kim wrote:
> > > With "detach-all=on" for display, QEMU starts with all VC windows
> > > detached automatically.
> > > 
> > > If used with "full-screen=on", it places individual windows (from
> > > top window) starting from monitor 0 or monitor n in case monitor=n.
> > > 
> > > In case # mon < # VCs, only same number of VCs as # mon will be sent to
> > > the monitors for full-screen while others are remaining in windowed-mode.
> > > 
> > > Target monitor number for individual VC is rotated in case monitor=n
> > > (n != 0) (e.g. if monitor=1 and # VCs = 2, the top window will be
> > > full-screened on monitor 1 and top second window will be full-screened
> > > on monitor 0.)
> > 
> > I tend to wonder whether we actually need this at all, as opposed
> > to just changing QEMU's behaviour by default.
> > 
> > It makes sense to have tabs per-VC for the things like the HMP
> > console, serial ports, etc, but I think graphical video outputs
> > should always be displayed as multiple windows. Putting graphical
> > outputs as tabs rather defeats the purpose of having multiple
> > outputs IMHO. 
> > 
> > IOW, why won't we just create 1 gtk window per graphical output
> > all the time.
> 
> I got your point but I think this requires changes in the
> policy, which I guess need community-wide agreement. Why don't we move
> on with this new option and at the same time start the discussion?

Once we add a CLI option is it is more complicated to remove it again
later. So if we don't actually need it, it is better not to add it in
the first place.

> One more point is, I tried to find out but I couldn't think of any good way
> to distinguish between guest output consoles and other consoles. Do you
> have any thought on this?

There's a helper:

  bool qemu_console_is_graphic(QemuConsole *con);
 

With regards,
Daniel
diff mbox series

Patch

diff --git a/qapi/ui.json b/qapi/ui.json
index ddcea7349b..a5b1550937 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -1378,6 +1378,8 @@ 
 # @show-cursor:   Force showing the mouse cursor (default: off).
 #                 (since: 5.0)
 # @gl:            Enable OpenGL support (default: off).
+# @detach-all:    Start QEMU with all VC windows detached (default: off)
+#                 (since: 7.1)
 #
 # Since: 2.12
 #
@@ -1387,7 +1389,8 @@ 
                 '*full-screen'   : 'bool',
                 '*window-close'  : 'bool',
                 '*show-cursor'   : 'bool',
-                '*gl'            : 'DisplayGLMode' },
+                '*gl'            : 'DisplayGLMode',
+                '*detach-all'    : 'bool' },
   'discriminator' : 'type',
   'data'    : {
       'gtk': { 'type': 'DisplayGTK', 'if': 'CONFIG_GTK' },
diff --git a/ui/gtk.c b/ui/gtk.c
index d9971d65ac..f1ca6a7275 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -2305,6 +2305,8 @@  static void gtk_display_init(DisplayState *ds, DisplayOptions *opts)
     GdkDisplay *window_display;
     GtkIconTheme *theme;
     char *dir;
+    int num_mon;
+    int i;
 
     if (!gtkinit) {
         fprintf(stderr, "gtk initialization failed\n");
@@ -2374,18 +2376,57 @@  static void gtk_display_init(DisplayState *ds, DisplayOptions *opts)
     gtk_widget_set_sensitive(s->copy_item,
                              vc && vc->type == GD_VC_VTE);
 #endif
-
     if (opts->u.gtk.has_monitor &&
-        opts->u.gtk.monitor < gdk_display_get_n_monitors(window_display)) {
+        opts->u.gtk.monitor <
+        (num_mon = gdk_display_get_n_monitors(window_display))) {
         GdkRectangle mon_dest;
         gdk_monitor_get_geometry(
             gdk_display_get_monitor(window_display, opts->u.gtk.monitor),
             &mon_dest);
         gtk_window_move(GTK_WINDOW(s->window), mon_dest.x, mon_dest.y);
     }
+    if (opts->has_detach_all &&
+        opts->detach_all) {
+        for (i = 0; i < s->nb_vcs - 1; i++) {
+            gtk_menu_item_activate(GTK_MENU_ITEM(s->untabify_item));
+        }
+    }
     if (opts->has_full_screen &&
         opts->full_screen) {
-        gtk_menu_item_activate(GTK_MENU_ITEM(s->full_screen_item));
+        bool no_mon_left = 0;
+        int next_mon = 0;
+        if (!opts->u.gtk.has_monitor ||
+	    (opts->u.gtk.has_monitor && opts->u.gtk.monitor < num_mon)) {
+            next_mon = (opts->u.gtk.has_monitor) ? opts->u.gtk.monitor : 0;
+            for (i = 0; i < s->nb_vcs - 1; i++) {
+                if (!s->vc[i].window) {
+                    continue;
+                }
+
+                gtk_window_fullscreen_on_monitor(
+                    GTK_WINDOW(s->vc[i].window),
+                    gdk_display_get_default_screen(window_display),
+                    next_mon++);
+
+                if (next_mon == opts->u.gtk.monitor) {
+                    no_mon_left = true;
+                    break;
+                }
+
+                if (next_mon == num_mon) {
+                    next_mon = 0;
+                }
+            }
+        }
+
+        if (!no_mon_left) {
+            GdkRectangle mon_dest;
+            gdk_monitor_get_geometry(
+                gdk_display_get_monitor(window_display, next_mon),
+                &mon_dest);
+            gtk_window_move(GTK_WINDOW(s->window), mon_dest.x, mon_dest.y);
+            gtk_menu_item_activate(GTK_MENU_ITEM(s->full_screen_item));
+        }
     }
     if (opts->u.gtk.has_grab_on_hover &&
         opts->u.gtk.grab_on_hover) {