Bugfix: Correctly handle unmap, don’t apply attribute XCB_EVENT_MASK_BUTTON_PRESS
Those two fix problems seen with mplayernext
parent
9e4b7f35ca
commit
d06fe8bc9e
|
@ -129,6 +129,10 @@ struct Client {
|
||||||
will reconfigure the client. */
|
will reconfigure the client. */
|
||||||
bool force_reconfigure;
|
bool force_reconfigure;
|
||||||
|
|
||||||
|
/* When reparenting a window, an unmap-notify is sent. As we delete windows when they’re
|
||||||
|
unmapped, we need to ignore that one. Therefore, this flag is set when reparenting. */
|
||||||
|
bool awaiting_useless_unmap;
|
||||||
|
|
||||||
/* XCB contexts */
|
/* XCB contexts */
|
||||||
xcb_window_t frame; /* Our window: The frame around the client */
|
xcb_window_t frame; /* Our window: The frame around the client */
|
||||||
xcb_gcontext_t titlegc; /* The titlebar’s graphic context inside the frame */
|
xcb_gcontext_t titlegc; /* The titlebar’s graphic context inside the frame */
|
||||||
|
|
|
@ -299,32 +299,29 @@ int handle_map_notify_event(void *prophs, xcb_connection_t *conn, xcb_map_notify
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int handle_unmap_notify_event(void *data, xcb_connection_t *c, xcb_unmap_notify_event_t *e) {
|
int handle_unmap_notify_event(void *data, xcb_connection_t *c, xcb_unmap_notify_event_t *e) {
|
||||||
Client *client = table_remove(byChild, e->event);
|
xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(c)).data->root;
|
||||||
xcb_window_t root;
|
|
||||||
|
Client *client = table_get(byChild, e->window);
|
||||||
|
/* First, we need to check if the client is awaiting an unmap-request which
|
||||||
|
was generated by us reparenting the window. In that case, we just ignore it. */
|
||||||
|
if (client != NULL && client->awaiting_useless_unmap) {
|
||||||
|
printf("Dropping this unmap request, it was generated by reparenting\n");
|
||||||
|
client->awaiting_useless_unmap = false;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
client = table_remove(byChild, e->window);
|
||||||
|
|
||||||
printf("UnmapNotify for 0x%08x (received from 0x%08x): ", e->window, e->event);
|
printf("UnmapNotify for 0x%08x (received from 0x%08x): ", e->window, e->event);
|
||||||
if(!client)
|
if(client == NULL) {
|
||||||
{
|
|
||||||
printf("not a managed window. Ignoring.\n");
|
printf("not a managed window. Ignoring.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rows, cols;
|
|
||||||
Client *con_client;
|
|
||||||
/* TODO: clear this up */
|
|
||||||
for (cols = 0; cols < c_ws->cols; cols++)
|
|
||||||
for (rows = 0; rows < c_ws->rows; rows++)
|
|
||||||
CIRCLEQ_FOREACH(con_client, &(CUR_TABLE[cols][rows]->clients), clients)
|
|
||||||
if (con_client == client) {
|
|
||||||
printf("removing from container\n");
|
|
||||||
if (client->container->currently_focused == client)
|
|
||||||
client->container->currently_focused = NULL;
|
|
||||||
CIRCLEQ_REMOVE(&(CUR_TABLE[cols][rows]->clients), con_client, clients);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (client->container->currently_focused == client)
|
||||||
|
client->container->currently_focused = NULL;
|
||||||
|
CIRCLEQ_REMOVE(&(client->container->clients), client, clients);
|
||||||
|
|
||||||
|
|
||||||
root = xcb_setup_roots_iterator(xcb_get_setup(c)).data->root;
|
|
||||||
printf("child of 0x%08x.\n", client->frame);
|
printf("child of 0x%08x.\n", client->frame);
|
||||||
xcb_reparent_window(c, client->child, root, 0, 0);
|
xcb_reparent_window(c, client->child, root, 0, 0);
|
||||||
xcb_destroy_window(c, client->frame);
|
xcb_destroy_window(c, client->frame);
|
||||||
|
|
13
src/mainx.c
13
src/mainx.c
|
@ -49,9 +49,6 @@ Display *xkbdpy;
|
||||||
TAILQ_HEAD(bindings_head, Binding) bindings;
|
TAILQ_HEAD(bindings_head, Binding) bindings;
|
||||||
xcb_event_handlers_t evenths;
|
xcb_event_handlers_t evenths;
|
||||||
|
|
||||||
/* hm, xcb_wm wants us to implement this. */
|
|
||||||
table_t *byChild = 0;
|
|
||||||
table_t *byParent = 0;
|
|
||||||
xcb_window_t root_win;
|
xcb_window_t root_win;
|
||||||
xcb_atom_t atoms[6];
|
xcb_atom_t atoms[6];
|
||||||
|
|
||||||
|
@ -194,15 +191,17 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child,
|
||||||
table_put(byChild, child, new);
|
table_put(byChild, child, new);
|
||||||
|
|
||||||
/* Moves the original window into the new frame we've created for it */
|
/* Moves the original window into the new frame we've created for it */
|
||||||
xcb_reparent_window(conn, child, new->frame, 0, font->height);
|
new->awaiting_useless_unmap = true;
|
||||||
|
cookie = xcb_reparent_window_checked(conn, child, new->frame, 0, font->height);
|
||||||
|
check_error(conn, cookie, "Could not reparent window");
|
||||||
|
|
||||||
/* We are interested in property changes */
|
/* We are interested in property changes */
|
||||||
mask = XCB_CW_EVENT_MASK;
|
mask = XCB_CW_EVENT_MASK;
|
||||||
values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE |
|
values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE |
|
||||||
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
|
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
|
||||||
XCB_EVENT_MASK_ENTER_WINDOW |
|
XCB_EVENT_MASK_ENTER_WINDOW;
|
||||||
XCB_EVENT_MASK_BUTTON_PRESS;
|
cookie = xcb_change_window_attributes_checked(conn, child, mask, values);
|
||||||
xcb_change_window_attributes(conn, child, mask, values);
|
check_error(conn, cookie, "Could not change window attributes");
|
||||||
|
|
||||||
/* We need to grab the mouse buttons for click to focus */
|
/* We need to grab the mouse buttons for click to focus */
|
||||||
xcb_grab_button(conn, false, child, XCB_EVENT_MASK_BUTTON_PRESS,
|
xcb_grab_button(conn, false, child, XCB_EVENT_MASK_BUTTON_PRESS,
|
||||||
|
|
Loading…
Reference in New Issue