Merge pull request #1725 from psychon/current_time

Remove most uses of XCB_CURRENT_TIME
This commit is contained in:
Daniel Hahler 2017-04-18 14:17:05 +02:00 committed by GitHub
commit f2f8335ee5
7 changed files with 91 additions and 32 deletions

View File

@ -107,7 +107,7 @@ awesome_atexit(bool restart)
* Work around this by placing the focus where we like it to be. * Work around this by placing the focus where we like it to be.
*/ */
xcb_set_input_focus(globalconf.connection, XCB_INPUT_FOCUS_POINTER_ROOT, xcb_set_input_focus(globalconf.connection, XCB_INPUT_FOCUS_POINTER_ROOT,
XCB_NONE, XCB_CURRENT_TIME); XCB_NONE, globalconf.timestamp);
xcb_aux_sync(globalconf.connection); xcb_aux_sync(globalconf.connection);
xkb_free(); xkb_free();
@ -266,7 +266,7 @@ acquire_WM_Sn(bool replace)
/* Acquire the selection */ /* Acquire the selection */
xcb_set_selection_owner(globalconf.connection, globalconf.selection_owner_window, xcb_set_selection_owner(globalconf.connection, globalconf.selection_owner_window,
globalconf.selection_atom, XCB_CURRENT_TIME); globalconf.selection_atom, globalconf.timestamp);
if (get_sel_reply->owner != XCB_NONE) if (get_sel_reply->owner != XCB_NONE)
{ {
/* Wait for the old owner to go away */ /* Wait for the old owner to go away */
@ -286,7 +286,7 @@ acquire_WM_Sn(bool replace)
ev.window = globalconf.screen->root; ev.window = globalconf.screen->root;
ev.format = 32; ev.format = 32;
ev.type = MANAGER; ev.type = MANAGER;
ev.data.data32[0] = XCB_CURRENT_TIME; ev.data.data32[0] = globalconf.timestamp;
ev.data.data32[1] = globalconf.selection_atom; ev.data.data32[1] = globalconf.selection_atom;
ev.data.data32[2] = globalconf.selection_owner_window; ev.data.data32[2] = globalconf.selection_owner_window;
ev.data.data32[3] = ev.data.data32[4] = 0; ev.data.data32[3] = ev.data.data32[4] = 0;
@ -294,6 +294,49 @@ acquire_WM_Sn(bool replace)
xcb_send_event(globalconf.connection, false, globalconf.screen->root, 0xFFFFFF, (char *) &ev); xcb_send_event(globalconf.connection, false, globalconf.screen->root, 0xFFFFFF, (char *) &ev);
} }
static void
acquire_timestamp(void)
{
/* Getting a current timestamp is hard. ICCCM recommends a zero-length
* append to a property, so let's do that.
*/
xcb_generic_event_t *event;
xcb_window_t win = globalconf.screen->root;
xcb_atom_t atom = XCB_ATOM_RESOURCE_MANAGER; /* Just something random */
xcb_atom_t type = XCB_ATOM_STRING; /* Equally random */
xcb_grab_server(globalconf.connection);
xcb_change_window_attributes(globalconf.connection, win,
XCB_CW_EVENT_MASK, (uint32_t[]) { XCB_EVENT_MASK_PROPERTY_CHANGE });
xcb_change_property(globalconf.connection, XCB_PROP_MODE_APPEND, win,
atom, type, 8, 0, "");
xcb_change_window_attributes(globalconf.connection, win,
XCB_CW_EVENT_MASK, (uint32_t[]) { 0 });
xcb_ungrab_server(globalconf.connection);
xcb_flush(globalconf.connection);
/* Now wait for the event */
while((event = xcb_wait_for_event(globalconf.connection)))
{
/* Is it the event we are waiting for? */
if(XCB_EVENT_RESPONSE_TYPE(event) == XCB_PROPERTY_NOTIFY)
{
xcb_property_notify_event_t *ev = (void *) event;
globalconf.timestamp = ev->time;
p_delete(&event);
break;
}
/* Hm, not the right event. */
if (globalconf.pending_event != NULL)
{
event_handle(globalconf.pending_event);
p_delete(&globalconf.pending_event);
}
globalconf.pending_event = event;
}
}
static xcb_generic_event_t *poll_for_event(void) static xcb_generic_event_t *poll_for_event(void)
{ {
if (globalconf.pending_event) { if (globalconf.pending_event) {
@ -635,6 +678,9 @@ main(int argc, char **argv)
globalconf.visual->visual_id); globalconf.visual->visual_id);
} }
/* Get a recent timestamp */
acquire_timestamp();
/* Prefetch all the extensions we might need */ /* Prefetch all the extensions we might need */
xcb_prefetch_extension_data(globalconf.connection, &xcb_big_requests_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_big_requests_id);
xcb_prefetch_extension_data(globalconf.connection, &xcb_test_id); xcb_prefetch_extension_data(globalconf.connection, &xcb_test_id);

View File

@ -37,7 +37,7 @@ void luaA_systray_invalidate(void);
*/ */
void void
xembed_message_send(xcb_connection_t *connection, xcb_window_t towin, xembed_message_send(xcb_connection_t *connection, xcb_window_t towin,
long message, long d1, long d2, long d3) xcb_timestamp_t timestamp, uint32_t message, uint32_t d1, uint32_t d2, uint32_t d3)
{ {
xcb_client_message_event_t ev; xcb_client_message_event_t ev;
@ -45,7 +45,7 @@ xembed_message_send(xcb_connection_t *connection, xcb_window_t towin,
ev.response_type = XCB_CLIENT_MESSAGE; ev.response_type = XCB_CLIENT_MESSAGE;
ev.window = towin; ev.window = towin;
ev.format = 32; ev.format = 32;
ev.data.data32[0] = XCB_CURRENT_TIME; ev.data.data32[0] = timestamp;
ev.data.data32[1] = message; ev.data.data32[1] = message;
ev.data.data32[2] = d1; ev.data.data32[2] = d1;
ev.data.data32[3] = d2; ev.data.data32[3] = d2;
@ -116,10 +116,12 @@ xembed_getbywin(xembed_window_array_t *list, xcb_window_t win)
/** Update embedded window properties. /** Update embedded window properties.
* \param connection The X connection. * \param connection The X connection.
* \param emwin The embedded window. * \param emwin The embedded window.
* \param timestamp The timestamp.
* \param reply The property reply to handle.
*/ */
void void
xembed_property_update(xcb_connection_t *connection, xembed_window_t *emwin, xembed_property_update(xcb_connection_t *connection, xembed_window_t *emwin,
xcb_get_property_reply_t *reply) xcb_timestamp_t timestamp, xcb_get_property_reply_t *reply)
{ {
int flags_changed; int flags_changed;
xembed_info_t info = { 0, 0 }; xembed_info_t info = { 0, 0 };
@ -136,13 +138,13 @@ xembed_property_update(xcb_connection_t *connection, xembed_window_t *emwin,
if(info.flags & XEMBED_MAPPED) if(info.flags & XEMBED_MAPPED)
{ {
xcb_map_window(connection, emwin->win); xcb_map_window(connection, emwin->win);
xembed_window_activate(connection, emwin->win); xembed_window_activate(connection, emwin->win, timestamp);
} }
else else
{ {
xcb_unmap_window(connection, emwin->win); xcb_unmap_window(connection, emwin->win);
xembed_window_deactivate(connection, emwin->win); xembed_window_deactivate(connection, emwin->win, timestamp);
xembed_focus_out(connection, emwin->win); xembed_focus_out(connection, emwin->win, timestamp);
} }
luaA_systray_invalidate(); luaA_systray_invalidate();
} }

View File

@ -87,9 +87,9 @@ DO_ARRAY(xembed_window_t, xembed_window, DO_NOTHING)
#define XEMBED_ACCELERATOR_OVERLOADED (1 << 0) #define XEMBED_ACCELERATOR_OVERLOADED (1 << 0)
void xembed_message_send(xcb_connection_t *, xcb_window_t, long, long, long, long); void xembed_message_send(xcb_connection_t *, xcb_window_t, xcb_timestamp_t, uint32_t, uint32_t, uint32_t, uint32_t);
xembed_window_t * xembed_getbywin(xembed_window_array_t *, xcb_window_t); xembed_window_t * xembed_getbywin(xembed_window_array_t *, xcb_window_t);
void xembed_property_update(xcb_connection_t *, xembed_window_t *, xcb_get_property_reply_t *); void xembed_property_update(xcb_connection_t *, xembed_window_t *, xcb_timestamp_t, xcb_get_property_reply_t *);
xcb_get_property_cookie_t xembed_info_get_unchecked(xcb_connection_t *, xcb_get_property_cookie_t xembed_info_get_unchecked(xcb_connection_t *,
xcb_window_t); xcb_window_t);
bool xembed_info_get_reply(xcb_connection_t *connection, bool xembed_info_get_reply(xcb_connection_t *connection,
@ -100,46 +100,50 @@ bool xembed_info_get_reply(xcb_connection_t *connection,
/** Indicate to an embedded window that it has focus. /** Indicate to an embedded window that it has focus.
* \param c The X connection. * \param c The X connection.
* \param client The client. * \param client The client.
* \param timestamp The timestamp.
* \param focus_type The type of focus. * \param focus_type The type of focus.
*/ */
static inline void static inline void
xembed_focus_in(xcb_connection_t *c, xcb_window_t client, long focus_type) xembed_focus_in(xcb_connection_t *c, xcb_window_t client, xcb_timestamp_t timestamp, uint32_t focus_type)
{ {
xembed_message_send(c, client, XEMBED_FOCUS_IN, focus_type, 0, 0); xembed_message_send(c, client, timestamp, XEMBED_FOCUS_IN, focus_type, 0, 0);
} }
/** Notify a window that it has become active. /** Notify a window that it has become active.
* \param c The X connection. * \param c The X connection.
* \param client The window to notify. * \param client The window to notify.
* \param timestamp The timestamp.
*/ */
static inline void static inline void
xembed_window_activate(xcb_connection_t *c, xcb_window_t client) xembed_window_activate(xcb_connection_t *c, xcb_window_t client, xcb_timestamp_t timestamp)
{ {
xembed_message_send(c, client, XEMBED_WINDOW_ACTIVATE, 0, 0, 0); xembed_message_send(c, client, timestamp, XEMBED_WINDOW_ACTIVATE, 0, 0, 0);
} }
/** Notify a window that it has become inactive. /** Notify a window that it has become inactive.
* \param c The X connection. * \param c The X connection.
* \param client The window to notify. * \param client The window to notify.
* \param timestamp The timestamp.
*/ */
static inline static inline
void xembed_window_deactivate(xcb_connection_t *c, xcb_window_t client) void xembed_window_deactivate(xcb_connection_t *c, xcb_window_t client, xcb_timestamp_t timestamp)
{ {
xembed_message_send(c, client, XEMBED_WINDOW_DEACTIVATE, 0, 0, 0); xembed_message_send(c, client, timestamp, XEMBED_WINDOW_DEACTIVATE, 0, 0, 0);
} }
/** Notify a window that its embed request has been received and accepted. /** Notify a window that its embed request has been received and accepted.
* \param c The X connection. * \param c The X connection.
* \param client The client to send message to. * \param client The client to send message to.
* \param timestamp The timestamp.
* \param embedder The embedder window. * \param embedder The embedder window.
* \param version The version. * \param version The version.
*/ */
static inline void static inline void
xembed_embedded_notify(xcb_connection_t *c, xembed_embedded_notify(xcb_connection_t *c,
xcb_window_t client, xcb_window_t embedder, xcb_window_t client, xcb_timestamp_t timestamp,
long version) xcb_window_t embedder, uint32_t version)
{ {
xembed_message_send(c, client, XEMBED_EMBEDDED_NOTIFY, 0, embedder, version); xembed_message_send(c, client, timestamp, XEMBED_EMBEDDED_NOTIFY, 0, embedder, version);
} }
/** Have the embedder end XEMBED protocol communication with a child. /** Have the embedder end XEMBED protocol communication with a child.
@ -156,11 +160,12 @@ xembed_window_unembed(xcb_connection_t *connection, xcb_window_t child, xcb_wind
/** Indicate to an embedded window that it has lost focus. /** Indicate to an embedded window that it has lost focus.
* \param c The X connection. * \param c The X connection.
* \param client The client to send message to. * \param client The client to send message to.
* \param timestamp The timestamp.
*/ */
static inline void static inline void
xembed_focus_out(xcb_connection_t *c, xcb_window_t client) xembed_focus_out(xcb_connection_t *c, xcb_window_t client, xcb_timestamp_t timestamp)
{ {
xembed_message_send(c, client, XEMBED_FOCUS_OUT, 0, 0, 0); xembed_message_send(c, client, timestamp, XEMBED_FOCUS_OUT, 0, 0, 0);
} }

10
event.c
View File

@ -221,7 +221,7 @@ event_handle_button(xcb_button_press_event_t *ev)
if(ev->child == XCB_NONE) if(ev->child == XCB_NONE)
xcb_allow_events(globalconf.connection, xcb_allow_events(globalconf.connection,
XCB_ALLOW_ASYNC_POINTER, XCB_ALLOW_ASYNC_POINTER,
XCB_CURRENT_TIME); ev->time);
} }
else if((c = client_getbyframewin(ev->event)) || (c = client_getbywin(ev->event))) else if((c = client_getbyframewin(ev->event)) || (c = client_getbywin(ev->event)))
{ {
@ -263,7 +263,7 @@ event_handle_button(xcb_button_press_event_t *ev)
} }
xcb_allow_events(globalconf.connection, xcb_allow_events(globalconf.connection,
XCB_ALLOW_REPLAY_POINTER, XCB_ALLOW_REPLAY_POINTER,
XCB_CURRENT_TIME); ev->time);
} }
else if(ev->child == XCB_NONE) else if(ev->child == XCB_NONE)
if(globalconf.screen->root == ev->event) if(globalconf.screen->root == ev->event)
@ -751,7 +751,7 @@ event_handle_maprequest(xcb_map_request_event_t *ev)
if((em = xembed_getbywin(&globalconf.embedded, ev->window))) if((em = xembed_getbywin(&globalconf.embedded, ev->window)))
{ {
xcb_map_window(globalconf.connection, ev->window); xcb_map_window(globalconf.connection, ev->window);
xembed_window_activate(globalconf.connection, ev->window); xembed_window_activate(globalconf.connection, ev->window, globalconf.timestamp);
/* The correct way to set this is via the _XEMBED_INFO property. Neither /* The correct way to set this is via the _XEMBED_INFO property. Neither
* of the XEMBED not the systray spec talk about mapping windows. * of the XEMBED not the systray spec talk about mapping windows.
* Apparently, Qt doesn't care and does not set an _XEMBED_INFO * Apparently, Qt doesn't care and does not set an _XEMBED_INFO
@ -837,6 +837,10 @@ event_handle_randr_output_change_notify(xcb_randr_notify_event_t *ev)
xcb_randr_get_output_info_reply_t *info = NULL; xcb_randr_get_output_info_reply_t *info = NULL;
lua_State *L = globalconf_get_lua_State(); lua_State *L = globalconf_get_lua_State();
/* The following explicitly uses XCB_CURRENT_TIME since we want to know
* the final state of the connection. There could be more notification
* events underway and using some "old" timestamp causes problems.
*/
info = xcb_randr_get_output_info_reply(globalconf.connection, info = xcb_randr_get_output_info_reply(globalconf.connection,
xcb_randr_get_output_info_unchecked(globalconf.connection, xcb_randr_get_output_info_unchecked(globalconf.connection,
output, output,

View File

@ -341,7 +341,8 @@ property_handle_xembed_info(uint8_t state,
XCB_GET_PROPERTY_TYPE_ANY, 0, 3); XCB_GET_PROPERTY_TYPE_ANY, 0, 3);
xcb_get_property_reply_t *propr = xcb_get_property_reply_t *propr =
xcb_get_property_reply(globalconf.connection, cookie, 0); xcb_get_property_reply(globalconf.connection, cookie, 0);
xembed_property_update(globalconf.connection, emwin, propr); xembed_property_update(globalconf.connection, emwin,
globalconf.timestamp, propr);
p_delete(&propr); p_delete(&propr);
} }

2
root.c
View File

@ -276,7 +276,7 @@ luaA_root_fake_input(lua_State *L)
xcb_test_fake_input(globalconf.connection, xcb_test_fake_input(globalconf.connection,
type, type,
detail, detail,
XCB_CURRENT_TIME, 0, /* This is a delay, not a timestamp! */
XCB_NONE, XCB_NONE,
x, y, x, y,
0); 0);

View File

@ -90,7 +90,7 @@ systray_register(void)
ev.window = xscreen->root; ev.window = xscreen->root;
ev.format = 32; ev.format = 32;
ev.type = MANAGER; ev.type = MANAGER;
ev.data.data32[0] = XCB_CURRENT_TIME; ev.data.data32[0] = globalconf.timestamp;
ev.data.data32[1] = globalconf.systray.atom; ev.data.data32[1] = globalconf.systray.atom;
ev.data.data32[2] = globalconf.systray.window; ev.data.data32[2] = globalconf.systray.window;
ev.data.data32[3] = ev.data.data32[4] = 0; ev.data.data32[3] = ev.data.data32[4] = 0;
@ -98,7 +98,7 @@ systray_register(void)
xcb_set_selection_owner(globalconf.connection, xcb_set_selection_owner(globalconf.connection,
globalconf.systray.window, globalconf.systray.window,
globalconf.systray.atom, globalconf.systray.atom,
XCB_CURRENT_TIME); globalconf.timestamp);
xcb_send_event(globalconf.connection, false, xscreen->root, 0xFFFFFF, (char *) &ev); xcb_send_event(globalconf.connection, false, xscreen->root, 0xFFFFFF, (char *) &ev);
} }
@ -116,7 +116,7 @@ systray_cleanup(void)
xcb_set_selection_owner(globalconf.connection, xcb_set_selection_owner(globalconf.connection,
XCB_NONE, XCB_NONE,
globalconf.systray.atom, globalconf.systray.atom,
XCB_CURRENT_TIME); globalconf.timestamp);
xcb_unmap_window(globalconf.connection, xcb_unmap_window(globalconf.connection,
globalconf.systray.window); globalconf.systray.window);
@ -166,7 +166,7 @@ systray_request_handle(xcb_window_t embed_win)
} }
xembed_embedded_notify(globalconf.connection, em.win, xembed_embedded_notify(globalconf.connection, em.win,
globalconf.systray.window, globalconf.timestamp, globalconf.systray.window,
MIN(XEMBED_VERSION, em.info.version)); MIN(XEMBED_VERSION, em.info.version));
xembed_window_array_append(&globalconf.embedded, em); xembed_window_array_append(&globalconf.embedded, em);
@ -241,7 +241,8 @@ xembed_process_client_message(xcb_client_message_event_t *ev)
switch(ev->data.data32[1]) switch(ev->data.data32[1])
{ {
case XEMBED_REQUEST_FOCUS: case XEMBED_REQUEST_FOCUS:
xembed_focus_in(globalconf.connection, ev->window, XEMBED_FOCUS_CURRENT); xembed_focus_in(globalconf.connection, ev->window,
globalconf.timestamp, XEMBED_FOCUS_CURRENT);
break; break;
} }
return 0; return 0;