[PATCH v4 04/10] char-mux: add support for the terminal size

Filip Hejsek posted 10 patches 2 weeks, 2 days ago
Maintainers: "Gonglei (Arei)" <arei.gonglei@huawei.com>, Zhenwei Pi <pizhenwei@bytedance.com>, "Michael S. Tsirkin" <mst@redhat.com>, Stefano Garzarella <sgarzare@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, Raphael Norwitz <raphael@enfabrica.net>, Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>, Thomas Huth <thuth@redhat.com>, Halil Pasic <pasic@linux.ibm.com>, Christian Borntraeger <borntraeger@linux.ibm.com>, "Collin L. Walling" <walling@linux.ibm.com>, Laurent Vivier <lvivier@redhat.com>, Amit Shah <amit@kernel.org>, Eduardo Habkost <eduardo@habkost.net>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Yanan Wang <wangyanan55@huawei.com>, Zhao Liu <zhao1.liu@intel.com>, Corey Minyard <minyard@acm.org>, Fam Zheng <fam@euphon.net>, Samuel Thibault <samuel.thibault@ens-lyon.org>, "Alex Bennée" <alex.bennee@linaro.org>, "Dr. David Alan Gilbert" <dave@treblig.org>, Markus Armbruster <armbru@redhat.com>, Jason Wang <jasowang@redhat.com>, Eric Blake <eblake@redhat.com>
There is a newer version of this series
[PATCH v4 04/10] char-mux: add support for the terminal size
Posted by Filip Hejsek 2 weeks, 2 days ago
From: Szymon Lukasz <noh4hss@gmail.com>

The terminal size of a mux chardev should be the same as the real
chardev, so listen for CHR_EVENT_RESIZE to be up to date.

We forward CHR_EVENT_RESIZE only to the focused frontend. This means
frontends should probably update their view of the terminal size on
receiving CHR_EVENT_MUX_IN.

Signed-off-by: Szymon Lukasz <noh4hss@gmail.com>
Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
---
 chardev/char-mux.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/chardev/char-mux.c b/chardev/char-mux.c
index 6b36290e2c49f579580d2abb5aa552806f019d4a..4d3d05b82f13e002c766142f9d9c24977b8b9bd2 100644
--- a/chardev/char-mux.c
+++ b/chardev/char-mux.c
@@ -264,9 +264,24 @@ void mux_chr_send_all_event(Chardev *chr, QEMUChrEvent event)
     }
 }
 
+static void mux_update_winsize(Chardev *chr)
+{
+    MuxChardev *d = MUX_CHARDEV(chr);
+    uint16_t cols, rows;
+
+    qemu_chr_fe_get_winsize(&d->chr, &cols, &rows);
+    qemu_chr_resize(chr, cols, rows);
+}
+
 static void mux_chr_event(void *opaque, QEMUChrEvent event)
 {
-    mux_chr_send_all_event(CHARDEV(opaque), event);
+    Chardev *chr = CHARDEV(opaque);
+
+    if (event == CHR_EVENT_RESIZE) {
+        mux_update_winsize(chr);
+    } else {
+        mux_chr_send_all_event(chr, event);
+    }
 }
 
 static GSource *mux_chr_add_watch(Chardev *s, GIOCondition cond)
@@ -382,6 +397,7 @@ static void qemu_chr_open_mux(Chardev *chr,
      */
     *be_opened = muxes_opened;
     qemu_chr_fe_init(&d->chr, drv, errp);
+    mux_update_winsize(chr);
 }
 
 static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend,

-- 
2.51.0
Re: [PATCH v4 04/10] char-mux: add support for the terminal size
Posted by Maximilian Immanuel Brandtner 1 week, 3 days ago
On Fri, 2025-09-12 at 05:39 +0200, Filip Hejsek wrote:
> From: Szymon Lukasz <noh4hss@gmail.com>
> 
> The terminal size of a mux chardev should be the same as the real
> chardev, so listen for CHR_EVENT_RESIZE to be up to date.
> 
> We forward CHR_EVENT_RESIZE only to the focused frontend. This means
> frontends should probably update their view of the terminal size on
> receiving CHR_EVENT_MUX_IN.
> 
> Signed-off-by: Szymon Lukasz <noh4hss@gmail.com>
> Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
> ---
>  chardev/char-mux.c | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/chardev/char-mux.c b/chardev/char-mux.c
> index
> 6b36290e2c49f579580d2abb5aa552806f019d4a..4d3d05b82f13e002c766142f9d9
> c24977b8b9bd2 100644
> --- a/chardev/char-mux.c
> +++ b/chardev/char-mux.c
> @@ -264,9 +264,24 @@ void mux_chr_send_all_event(Chardev *chr,
> QEMUChrEvent event)
>      }
>  }
>  
> +static void mux_update_winsize(Chardev *chr)
> +{
> +    MuxChardev *d = MUX_CHARDEV(chr);
> +    uint16_t cols, rows;
> +
> +    qemu_chr_fe_get_winsize(&d->chr, &cols, &rows);
> +    qemu_chr_resize(chr, cols, rows);
> +}
> +
>  static void mux_chr_event(void *opaque, QEMUChrEvent event)
>  {
> -    mux_chr_send_all_event(CHARDEV(opaque), event);
> +    Chardev *chr = CHARDEV(opaque);
> +
> +    if (event == CHR_EVENT_RESIZE) {
> +        mux_update_winsize(chr);
> +    } else {
> +        mux_chr_send_all_event(chr, event);
> +    }
>  }
>  
>  static GSource *mux_chr_add_watch(Chardev *s, GIOCondition cond)
> @@ -382,6 +397,7 @@ static void qemu_chr_open_mux(Chardev *chr,
>       */
>      *be_opened = muxes_opened;
>      qemu_chr_fe_init(&d->chr, drv, errp);
> +    mux_update_winsize(chr);
>  }
>  
>  static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend
> *backend,
> 

When changing the focussed chardev, the MuxChardev should send a resize
event to the newly focussed chardev. Otherwise the size information of
the focussed chardev might be outdated if it wasn't the focussed
chardev at the time of the resize event.

Theoretically, the resize event could also just be sent to all
character devices focussed or not, however as this causes a lot of
needless redrawing I prefer the approach of only resizing the focussed
chardev.

Kind regards,
Max Brandtner
Re: [PATCH v4 04/10] char-mux: add support for the terminal size
Posted by Filip Hejsek 1 week, 3 days ago
On September 18, 2025 10:32:57 AM GMT+02:00, Maximilian Immanuel Brandtner <maxbr@linux.ibm.com> wrote:
> On Fri, 2025-09-12 at 05:39 +0200, Filip Hejsek wrote:
> > From: Szymon Lukasz <noh4hss@gmail.com>
> > 
> > The terminal size of a mux chardev should be the same as the real
> > chardev, so listen for CHR_EVENT_RESIZE to be up to date.
> > 
> > We forward CHR_EVENT_RESIZE only to the focused frontend. This means
> > frontends should probably update their view of the terminal size on
> > receiving CHR_EVENT_MUX_IN.
> > 
> > Signed-off-by: Szymon Lukasz <noh4hss@gmail.com>
> > Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
> > ---
> >  chardev/char-mux.c | 18 +++++++++++++++++-
> >  1 file changed, 17 insertions(+), 1 deletion(-)
> > 
> > diff --git a/chardev/char-mux.c b/chardev/char-mux.c
> > index
> > 6b36290e2c49f579580d2abb5aa552806f019d4a..4d3d05b82f13e002c766142f9d9
> > c24977b8b9bd2 100644
> > --- a/chardev/char-mux.c
> > +++ b/chardev/char-mux.c
> > @@ -264,9 +264,24 @@ void mux_chr_send_all_event(Chardev *chr,
> > QEMUChrEvent event)
> >      }
> >  }
> >  
> > +static void mux_update_winsize(Chardev *chr)
> > +{
> > +    MuxChardev *d = MUX_CHARDEV(chr);
> > +    uint16_t cols, rows;
> > +
> > +    qemu_chr_fe_get_winsize(&d->chr, &cols, &rows);
> > +    qemu_chr_resize(chr, cols, rows);
> > +}
> > +
> >  static void mux_chr_event(void *opaque, QEMUChrEvent event)
> >  {
> > -    mux_chr_send_all_event(CHARDEV(opaque), event);
> > +    Chardev *chr = CHARDEV(opaque);
> > +
> > +    if (event == CHR_EVENT_RESIZE) {
> > +        mux_update_winsize(chr);
> > +    } else {
> > +        mux_chr_send_all_event(chr, event);
> > +    }
> >  }
> >  
> >  static GSource *mux_chr_add_watch(Chardev *s, GIOCondition cond)
> > @@ -382,6 +397,7 @@ static void qemu_chr_open_mux(Chardev *chr,
> >       */
> >      *be_opened = muxes_opened;
> >      qemu_chr_fe_init(&d->chr, drv, errp);
> > +    mux_update_winsize(chr);
> >  }
> >  
> >  static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend
> > *backend,
> > 
> 
> When changing the focussed chardev, the MuxChardev should send a resize
> event to the newly focussed chardev. Otherwise the size information of
> the focussed chardev might be outdated if it wasn't the focussed
> chardev at the time of the resize event.
> 
> Theoretically, the resize event could also just be sent to all
> character devices focussed or not, however as this causes a lot of
> needless redrawing I prefer the approach of only resizing the focussed
> chardev.
> 
> Kind regards,
> Max Brandtner
> 

Right now, this is handled by frontends also updating the size
on CHR_EVENT_MUX_IN, as mentioned in the commit message.
I could make it so that CHR_EVENT_MUX_IN is always followed
by CHR_EVENT_RESIZE, if that is preferred. A more complicated
option is to remember for each frontend if it missed a resize event,
and only send it then, but that seems like needless complexity.

Kind regards,
Filip