Merge branch 'speedup-ignore_enterleave'

This commit is contained in:
Uli Schlachter 2016-09-30 10:11:07 +02:00
commit cd3d82d6f9
6 changed files with 70 additions and 27 deletions

View File

@ -8,8 +8,6 @@ set(CODENAME "The Fox")
project(${PROJECT_AWE_NAME} C)
set(CMAKE_BUILD_TYPE RELEASE)
option(WITH_DBUS "build with D-BUS" ON)
option(GENERATE_MANPAGES "generate manpages" ON)
option(COMPRESS_MANPAGES "compress manpages" ON)

33
event.c
View File

@ -991,10 +991,43 @@ xerror(xcb_generic_error_t *e)
return;
}
static bool
should_ignore(xcb_generic_event_t *event)
{
uint8_t response_type = XCB_EVENT_RESPONSE_TYPE(event);
/* Remove completed sequences */
uint32_t sequence = event->full_sequence;
while (globalconf.ignore_enter_leave_events.len > 0) {
uint32_t end = globalconf.ignore_enter_leave_events.tab[0].end.sequence;
/* Do if (end >= sequence) break;, but handle wrap-around: The above is
* equivalent to end-sequence > 0 (assuming unlimited precision). With
* int32_t, this would mean that the sign bit is cleared, which means:
*/
if (end - sequence < UINT32_MAX / 2)
break;
sequence_pair_array_take(&globalconf.ignore_enter_leave_events, 0);
}
/* Check if this event should be ignored */
if ((response_type == XCB_ENTER_NOTIFY || response_type == XCB_LEAVE_NOTIFY)
&& globalconf.ignore_enter_leave_events.len > 0) {
uint32_t begin = globalconf.ignore_enter_leave_events.tab[0].begin.sequence;
uint32_t end = globalconf.ignore_enter_leave_events.tab[0].end.sequence;
if (sequence >= begin && sequence <= end)
return true;
}
return false;
}
void event_handle(xcb_generic_event_t *event)
{
uint8_t response_type = XCB_EVENT_RESPONSE_TYPE(event);
if (should_ignore(event))
return;
if(response_type == 0)
{
/* This is an error, not a event */

View File

@ -55,6 +55,11 @@ typedef struct button_t button_t;
typedef struct client_t client_t;
typedef struct tag tag_t;
typedef struct xproperty xproperty_t;
struct sequence_pair {
xcb_void_cookie_t begin;
xcb_void_cookie_t end;
};
typedef struct sequence_pair sequence_pair_t;
ARRAY_TYPE(button_t *, button)
ARRAY_TYPE(tag_t *, tag)
@ -62,6 +67,7 @@ ARRAY_TYPE(screen_t *, screen)
ARRAY_TYPE(client_t *, client)
ARRAY_TYPE(drawin_t *, drawin)
ARRAY_TYPE(xproperty_t, xproperty)
DO_ARRAY(sequence_pair_t, sequence_pair, DO_NOTHING)
/** Main configuration structure */
typedef struct
@ -180,6 +186,9 @@ typedef struct
uint32_t preferred_icon_size;
/** Cached wallpaper information */
cairo_surface_t *wallpaper;
/** List of enter/leave events to ignore */
sequence_pair_array_t ignore_enter_leave_events;
xcb_void_cookie_t pending_enter_leave_begin;
} awesome_t;
extern awesome_t globalconf;

View File

@ -999,37 +999,36 @@ client_ban(client_t *c)
/** This is part of The Bob Marley Algorithm: we ignore enter and leave window
* in certain cases, like map/unmap or move, so we don't get spurious events.
* The implementation works by noting the range of sequence numbers for which we
* should ignore events. We grab the server to make sure that only we could
* generate events in this range.
*/
void
client_ignore_enterleave_events(void)
{
foreach(c, globalconf.clients)
{
xcb_change_window_attributes(globalconf.connection,
(*c)->window,
XCB_CW_EVENT_MASK,
(const uint32_t []) { CLIENT_SELECT_INPUT_EVENT_MASK & ~(XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW) });
xcb_change_window_attributes(globalconf.connection,
(*c)->frame_window,
XCB_CW_EVENT_MASK,
(const uint32_t []) { FRAME_SELECT_INPUT_EVENT_MASK & ~(XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW) });
}
assert(globalconf.pending_enter_leave_begin.sequence == 0);
globalconf.pending_enter_leave_begin = xcb_grab_server(globalconf.connection);
/* If the connection is broken, we get a request with sequence number 0
* which would then trigger an assertion in
* client_restore_enterleave_events(). Handle this nicely.
*/
if(xcb_connection_has_error(globalconf.connection))
fatal("X server connection broke (error %d)",
xcb_connection_has_error(globalconf.connection));
assert(globalconf.pending_enter_leave_begin.sequence != 0);
}
void
client_restore_enterleave_events(void)
{
foreach(c, globalconf.clients)
{
xcb_change_window_attributes(globalconf.connection,
(*c)->window,
XCB_CW_EVENT_MASK,
(const uint32_t []) { CLIENT_SELECT_INPUT_EVENT_MASK });
xcb_change_window_attributes(globalconf.connection,
(*c)->frame_window,
XCB_CW_EVENT_MASK,
(const uint32_t []) { FRAME_SELECT_INPUT_EVENT_MASK });
}
sequence_pair_t pair;
assert(globalconf.pending_enter_leave_begin.sequence != 0);
pair.begin = globalconf.pending_enter_leave_begin;
pair.end = xcb_no_operation(globalconf.connection);
xcb_ungrab_server(globalconf.connection);
globalconf.pending_enter_leave_begin.sequence = 0;
sequence_pair_array_append(&globalconf.ignore_enter_leave_events, pair);
}
/** Record that a client got focus.

View File

@ -297,10 +297,10 @@ static void
drawin_map(lua_State *L, int widx)
{
drawin_t *drawin = luaA_checkudata(L, widx, &drawin_class);
/* Activate BMA */
client_ignore_enterleave_events();
/* Apply any pending changes */
drawin_apply_moveresize(drawin);
/* Activate BMA */
client_ignore_enterleave_events();
/* Map the drawin */
xcb_map_window(globalconf.connection, drawin->window);
/* Deactivate BMA */

View File

@ -93,8 +93,12 @@ table.insert(steps, function()
x = w.x + w.width - 20 - 12.5,
y = w.y + 125 + 12.5,
}
return true
end)
assert(tt.current_position == "top")
-- Test that the above move had the intended effect
table.insert(steps, function()
assert(tt.current_position == "top", tt.current_position)
return true
end)