|
@@ -926,3 +926,101 @@ index daff1aa..61e60fa 100644
|
|
|
--
|
|
|
2.41.0
|
|
|
|
|
|
+From 00cdb145ca1f34e47a1c8ba0d933595709318f85 Mon Sep 17 00:00:00 2001
|
|
|
+From: osy <osy@turing.llc>
|
|
|
+Date: Sun, 17 Aug 2025 19:32:49 -0700
|
|
|
+Subject: [PATCH] main: only send physical size when used
|
|
|
+
|
|
|
+Since introducing physical size support four years ago, the
|
|
|
+feature has been broken on Linux. In VDAgent, there is a
|
|
|
+check on the size of VDAgentMonitorsConfig that does not
|
|
|
+account for FLAG_PHYSICAL_SIZE. This was fixed in VDAgent
|
|
|
+in commit 3660acfcbaaca9c66dca5ef09205bd7c1d70b98c but until
|
|
|
+that fix is released and all the Linux distros pick it up,
|
|
|
+the feature will still be broken.
|
|
|
+
|
|
|
+In the meantime, this change will ignore monitor physical
|
|
|
+size config if it is not used and the client can implement
|
|
|
+logic to detect when it is safe to send it.
|
|
|
+---
|
|
|
+ src/channel-main.c | 41 ++++++++++++++++++++++++++++-------------
|
|
|
+ 1 file changed, 28 insertions(+), 13 deletions(-)
|
|
|
+
|
|
|
+diff --git a/src/channel-main.c b/src/channel-main.c
|
|
|
+index 7830f6f..d4d1a1e 100644
|
|
|
+--- a/src/channel-main.c
|
|
|
++++ b/src/channel-main.c
|
|
|
+@@ -1119,6 +1119,7 @@ gboolean spice_main_channel_send_monitor_config(SpiceMainChannel *channel)
|
|
|
+ VDAgentMonitorsConfig *mon;
|
|
|
+ int i, j, monitors;
|
|
|
+ size_t size;
|
|
|
++ gboolean has_physical_size;
|
|
|
+
|
|
|
+ g_return_val_if_fail(SPICE_IS_MAIN_CHANNEL(channel), FALSE);
|
|
|
+ c = channel->priv;
|
|
|
+@@ -1134,8 +1135,18 @@ gboolean spice_main_channel_send_monitor_config(SpiceMainChannel *channel)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+- size = sizeof(VDAgentMonitorsConfig) +
|
|
|
+- (sizeof(VDAgentMonConfig) + sizeof(VDAgentMonitorMM)) * monitors;
|
|
|
++ /* only enable sending physical size if needed */
|
|
|
++ has_physical_size = FALSE;
|
|
|
++ for (i = 0; i < SPICE_N_ELEMENTS(c->display); i++) {
|
|
|
++ if (c->display[i].width_mm || c->display[i].height_mm) {
|
|
|
++ has_physical_size = TRUE;
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
++ size = sizeof(VDAgentMonitorsConfig) + sizeof(VDAgentMonConfig) * monitors;
|
|
|
++ if (has_physical_size) {
|
|
|
++ size += sizeof(VDAgentMonitorMM) * monitors;
|
|
|
++ }
|
|
|
+ mon = g_malloc0(size);
|
|
|
+
|
|
|
+ mon->num_of_monitors = monitors;
|
|
|
+@@ -1143,7 +1154,9 @@ gboolean spice_main_channel_send_monitor_config(SpiceMainChannel *channel)
|
|
|
+ c->disable_display_align == FALSE)
|
|
|
+ mon->flags |= VD_AGENT_CONFIG_MONITORS_FLAG_USE_POS;
|
|
|
+
|
|
|
+- mon->flags |= VD_AGENT_CONFIG_MONITORS_FLAG_PHYSICAL_SIZE;
|
|
|
++ if (has_physical_size) {
|
|
|
++ mon->flags |= VD_AGENT_CONFIG_MONITORS_FLAG_PHYSICAL_SIZE;
|
|
|
++ }
|
|
|
+
|
|
|
+ CHANNEL_DEBUG(channel, "sending new monitors config to guest");
|
|
|
+ j = 0;
|
|
|
+@@ -1166,18 +1179,20 @@ gboolean spice_main_channel_send_monitor_config(SpiceMainChannel *channel)
|
|
|
+ j++;
|
|
|
+ }
|
|
|
+
|
|
|
+- VDAgentMonitorMM *mm = (void *)&mon->monitors[monitors];
|
|
|
+- for (i = 0, j = 0; i < SPICE_N_ELEMENTS(c->display); i++) {
|
|
|
+- if (c->display[i].display_state != DISPLAY_ENABLED) {
|
|
|
+- if (spice_main_channel_agent_test_capability(channel,
|
|
|
+- VD_AGENT_CAP_SPARSE_MONITORS_CONFIG)) {
|
|
|
+- j++;
|
|
|
++ if (has_physical_size) {
|
|
|
++ VDAgentMonitorMM *mm = (void *)&mon->monitors[monitors];
|
|
|
++ for (i = 0, j = 0; i < SPICE_N_ELEMENTS(c->display); i++) {
|
|
|
++ if (c->display[i].display_state != DISPLAY_ENABLED) {
|
|
|
++ if (spice_main_channel_agent_test_capability(channel,
|
|
|
++ VD_AGENT_CAP_SPARSE_MONITORS_CONFIG)) {
|
|
|
++ j++;
|
|
|
++ }
|
|
|
++ continue;
|
|
|
+ }
|
|
|
+- continue;
|
|
|
++ mm[j].width = c->display[i].width_mm;
|
|
|
++ mm[j].height = c->display[i].height_mm;
|
|
|
++ j++;
|
|
|
+ }
|
|
|
+- mm[j].width = c->display[i].width_mm;
|
|
|
+- mm[j].height = c->display[i].height_mm;
|
|
|
+- j++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (c->disable_display_align == FALSE)
|
|
|
+--
|
|
|
+2.41.0
|
|
|
+
|