Skip to content

Commit 3d00bd5

Browse files
HW42marmarek
authored andcommitted
Don't try to send grants for not realized windows
We rely on composite redirect mode of the X server to get per window pixmaps. Those are setup/teared-down in compRealizeWindow/ compUnrealizeWindow (via compCheckRedirect). So not realized windows don't have a per window pixmap. Sending grant refs for them was always broken since we didn't send the offset into the screen pixmap in those cases. But with the recent change to not allocate grant refs for the screen pixmap this leads to a noticable error message. So don't try to send grant refs for not realized windows. This means that the configure before mapping will not contiain grant refs. We rely here very much on implementation details of the X server. In particular we require that a damage event is generated after the windows is realized. Note that the map event is generated before realization. Additionally we require that no damage event is delivered between the map notification the window being realized. Based on experimentation and code reading that seems to hold (what exactly triggers the first damage event after map depends on background settings and cursor position). This matches also that we so far haven't had problems even though this bug has been present for a long time.
1 parent c91197f commit 3d00bd5

2 files changed

Lines changed: 32 additions & 3 deletions

File tree

gui-agent/vmside.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ struct window_data {
150150
int support_delete_window;
151151
int support_take_focus;
152152
int window_dump_pending; /* send MSG_WINDOW_DUMP at next damage notification */
153+
int mapped;
153154
};
154155

155156
struct embeder_data {
@@ -492,6 +493,7 @@ static void process_xevent_createnotify(Ghandles * g, XCreateWindowEvent * ev)
492493
wd->support_delete_window = False;
493494
wd->support_take_focus = False;
494495
wd->window_dump_pending = False;
496+
wd->mapped = False;
495497
list_insert(windows_list, ev->window, wd);
496498

497499
if (attr.border_width > 0) {
@@ -911,6 +913,7 @@ static void process_xevent_map(Ghandles * g, XID window)
911913

912914
if (g->log_level > 1)
913915
fprintf(stderr, "MAP for window 0x%lx\n", window);
916+
wd->mapped = True;
914917
wd->window_dump_pending = True;
915918
send_window_state(g, window);
916919
XGetWindowAttributes(g->display, window, &attr);
@@ -935,13 +938,19 @@ static void process_xevent_map(Ghandles * g, XID window)
935938
static void process_xevent_unmap(Ghandles * g, XID window)
936939
{
937940
struct msg_hdr hdr;
941+
struct genlist *l;
942+
struct window_data *wd;
938943

939-
if (!lookup_window(g, windows_list, window, __func__)) {
944+
l = lookup_window(g, windows_list, window, __func__);
945+
if (!l) {
940946
return;
941947
}
942948

949+
wd = l->data;
950+
943951
if (g->log_level > 1)
944952
fprintf(stderr, "UNMAP for window 0x%lx\n", window);
953+
wd->mapped = False;
945954
hdr.type = MSG_UNMAP;
946955
hdr.window = window;
947956
hdr.untrusted_len = 0;
@@ -989,21 +998,25 @@ static void process_xevent_configure(Ghandles * g, XID window,
989998
struct msg_configure conf;
990999
struct genlist *l;
9911000
struct window_data *wd = NULL;
1001+
int mapped = False;
9921002

9931003
l = lookup_window(g, windows_list, window, NULL);
9941004
if (l) {
9951005
wd = l->data;
1006+
mapped = wd->mapped;
9961007
} else {
9971008
/* if not real managed window, check if this is embeder for another window */
9981009
struct genlist *e = lookup_window(g, embeder_list, window, NULL);
9991010
if (e) {
1011+
struct genlist *i;
10001012
window = ((struct embeder_data*)e->data)->icon_window;
1001-
if (!list_lookup(windows_list, window))
1013+
if (!(i = list_lookup(windows_list, window)))
10021014
/* probably icon window have just destroyed, so ignore message */
10031015
return;
10041016
/* l and wd not updated intentionally - when configure notify comes
10051017
* from the embeder, it should be passed to dom0 (in most cases as
10061018
* ACK for earlier configure request) */
1019+
mapped = ((struct window_data*)i->data)->mapped;
10071020
} else {
10081021
/* ignore not managed windows */
10091022
log_unmanaged_window(g, __func__, window);
@@ -1047,7 +1060,10 @@ static void process_xevent_configure(Ghandles * g, XID window,
10471060
conf.height = ev->height;
10481061
conf.override_redirect = ev->override_redirect;
10491062
write_message(g->vchan, hdr, conf);
1050-
send_pixmap_grant_refs(g, window);
1063+
if (mapped) {
1064+
// see comment in dump_window_grant_refs in the xdriver
1065+
send_pixmap_grant_refs(g, window);
1066+
}
10511067
}
10521068

10531069
static void send_clipboard_data(libvchan_t *vchan, XID window, char *data, uint32_t len, int protocol_version)

xf86-input-mfndev/src/qubes.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,19 @@ static void dump_window_grant_refs(int window_id, int fd)
604604
// the window is destroyed before the driver sees the req
605605
goto send_response;
606606

607+
if (!x_window->realized) {
608+
// Composite redirect is setup/teared-down during Realize-/Unrealize-
609+
// Window (called when a window gets mapped/unmapped). So if the window
610+
// is not realized we don't have a per window pixmap we can send.
611+
//
612+
// This means that the configure of a window before mapping will not
613+
// send grants. This should be fine since when compRealizeWindow
614+
// replaces the pixmap it will trigger a damage event and we will send
615+
// the grants then.
616+
xf86Msg(X_ERROR, "can't dump not realized window\n");
617+
goto send_response;
618+
}
619+
607620
screen = x_window->drawable.pScreen;
608621
pixmap = (*screen->GetWindowPixmap) (x_window);
609622

0 commit comments

Comments
 (0)