Skip to content

Commit 199284c

Browse files
authored
meta-monitor-manager-xrandr.c: DeleteMonitor before SetMonitor (#693)
A somewhat similar fix appears in mutter [1]. The RandR protocol [2] states concerning RRSetMonitor that: > If 'name' matches an existing Monitor on the screen, the > existing one will be deleted as if RRDeleteMonitor were called. Unfortunately, this behavior is not the case in practice, and if an existing monitor with the same name exists the server generates a BadValue error [3]. While this was fixed very recently in the Xorg xserver [3], it is unclear when these changes will make it to most distributions due to how long it has been since a formal Xorg xserver major release. Therefore, we must ourselves prevent muffin from aborting if a monitor with the same name already exists, a common condition upon restarting cinnamon or calling `cinnamon --replace`. The mutter fix [1] solves the problem of preventing mutter from aborting on the error, but the request still fails to set the monitor's outputs. The mutter fix also uses an API which is not in muffin yet. Therefore, we take the approach of using xcb to first delete any monitor with the name of the one which we wish to set. Note that this request can also fail if no such monitor exists, so we explicitly ignore this error. A word of warning to those who may wish to use xcb to also replace the SetMonitor call: a crashing bug was only recently fixed in libxcb [4] which caused all calls to xcb_randr_set_monitor() to crash or otherwise cause the calling program to behave in an undefined manner. While the fix is released in libxcb 1.17, this version is not even available in Ubuntu 24.04, for instance. Therefore, it may be some time before we can reliably call xcb_randr_set_monitor(). [1] https://gitlab.gnome.org/GNOME/mutter/-/commit/8d3696f39a0b3af725b7615f7e2ac74ce5e0bcbf [2] https://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt [3] https://gitlab.freedesktop.org/xorg/xserver/-/commit/146bb9b2c19fb75b7629b65d5871969b7fcef97a [4] https://gitlab.freedesktop.org/xorg/lib/libxcb/-/commit/038636786ad1914f3daf3503ae9611f40dffbb8f
1 parent c1a29cb commit 199284c

File tree

1 file changed

+7
-0
lines changed

1 file changed

+7
-0
lines changed

src/backends/x11/meta-monitor-manager-xrandr.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,8 @@ meta_monitor_manager_xrandr_tiled_monitor_added (MetaMonitorManager *manager,
10821082
GList *outputs;
10831083
GList *l;
10841084
int i;
1085+
xcb_connection_t *xcb_conn;
1086+
xcb_void_cookie_t cookie;
10851087

10861088
if (!(meta_monitor_manager_get_capabilities (manager) &
10871089
META_MONITOR_MANAGER_CAPABILITY_TILING))
@@ -1117,6 +1119,11 @@ meta_monitor_manager_xrandr_tiled_monitor_added (MetaMonitorManager *manager,
11171119
xrandr_monitor_info->outputs[i] = output->winsys_id;
11181120
}
11191121

1122+
xcb_conn = XGetXCBConnection (manager_xrandr->xdisplay);
1123+
cookie = xcb_randr_delete_monitor_checked (xcb_conn,
1124+
DefaultRootWindow (manager_xrandr->xdisplay),
1125+
name_atom);
1126+
free (xcb_request_check (xcb_conn, cookie)); /* ignore DeleteMonitor errors */
11201127
XRRSetMonitor (manager_xrandr->xdisplay,
11211128
DefaultRootWindow (manager_xrandr->xdisplay),
11221129
xrandr_monitor_info);

0 commit comments

Comments
 (0)