Merge branch 'speedup-ignore_enterleave'
This commit is contained in:
commit
cd3d82d6f9
|
@ -8,8 +8,6 @@ set(CODENAME "The Fox")
|
||||||
|
|
||||||
project(${PROJECT_AWE_NAME} C)
|
project(${PROJECT_AWE_NAME} C)
|
||||||
|
|
||||||
set(CMAKE_BUILD_TYPE RELEASE)
|
|
||||||
|
|
||||||
option(WITH_DBUS "build with D-BUS" ON)
|
option(WITH_DBUS "build with D-BUS" ON)
|
||||||
option(GENERATE_MANPAGES "generate manpages" ON)
|
option(GENERATE_MANPAGES "generate manpages" ON)
|
||||||
option(COMPRESS_MANPAGES "compress manpages" ON)
|
option(COMPRESS_MANPAGES "compress manpages" ON)
|
||||||
|
|
33
event.c
33
event.c
|
@ -991,10 +991,43 @@ xerror(xcb_generic_error_t *e)
|
||||||
return;
|
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)
|
void event_handle(xcb_generic_event_t *event)
|
||||||
{
|
{
|
||||||
uint8_t response_type = XCB_EVENT_RESPONSE_TYPE(event);
|
uint8_t response_type = XCB_EVENT_RESPONSE_TYPE(event);
|
||||||
|
|
||||||
|
if (should_ignore(event))
|
||||||
|
return;
|
||||||
|
|
||||||
if(response_type == 0)
|
if(response_type == 0)
|
||||||
{
|
{
|
||||||
/* This is an error, not a event */
|
/* This is an error, not a event */
|
||||||
|
|
|
@ -55,6 +55,11 @@ typedef struct button_t button_t;
|
||||||
typedef struct client_t client_t;
|
typedef struct client_t client_t;
|
||||||
typedef struct tag tag_t;
|
typedef struct tag tag_t;
|
||||||
typedef struct xproperty xproperty_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(button_t *, button)
|
||||||
ARRAY_TYPE(tag_t *, tag)
|
ARRAY_TYPE(tag_t *, tag)
|
||||||
|
@ -62,6 +67,7 @@ ARRAY_TYPE(screen_t *, screen)
|
||||||
ARRAY_TYPE(client_t *, client)
|
ARRAY_TYPE(client_t *, client)
|
||||||
ARRAY_TYPE(drawin_t *, drawin)
|
ARRAY_TYPE(drawin_t *, drawin)
|
||||||
ARRAY_TYPE(xproperty_t, xproperty)
|
ARRAY_TYPE(xproperty_t, xproperty)
|
||||||
|
DO_ARRAY(sequence_pair_t, sequence_pair, DO_NOTHING)
|
||||||
|
|
||||||
/** Main configuration structure */
|
/** Main configuration structure */
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -180,6 +186,9 @@ typedef struct
|
||||||
uint32_t preferred_icon_size;
|
uint32_t preferred_icon_size;
|
||||||
/** Cached wallpaper information */
|
/** Cached wallpaper information */
|
||||||
cairo_surface_t *wallpaper;
|
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;
|
} awesome_t;
|
||||||
|
|
||||||
extern awesome_t globalconf;
|
extern awesome_t globalconf;
|
||||||
|
|
|
@ -999,37 +999,36 @@ client_ban(client_t *c)
|
||||||
|
|
||||||
/** This is part of The Bob Marley Algorithm: we ignore enter and leave window
|
/** 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.
|
* 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
|
void
|
||||||
client_ignore_enterleave_events(void)
|
client_ignore_enterleave_events(void)
|
||||||
{
|
{
|
||||||
foreach(c, globalconf.clients)
|
assert(globalconf.pending_enter_leave_begin.sequence == 0);
|
||||||
{
|
globalconf.pending_enter_leave_begin = xcb_grab_server(globalconf.connection);
|
||||||
xcb_change_window_attributes(globalconf.connection,
|
/* If the connection is broken, we get a request with sequence number 0
|
||||||
(*c)->window,
|
* which would then trigger an assertion in
|
||||||
XCB_CW_EVENT_MASK,
|
* client_restore_enterleave_events(). Handle this nicely.
|
||||||
(const uint32_t []) { CLIENT_SELECT_INPUT_EVENT_MASK & ~(XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW) });
|
*/
|
||||||
xcb_change_window_attributes(globalconf.connection,
|
if(xcb_connection_has_error(globalconf.connection))
|
||||||
(*c)->frame_window,
|
fatal("X server connection broke (error %d)",
|
||||||
XCB_CW_EVENT_MASK,
|
xcb_connection_has_error(globalconf.connection));
|
||||||
(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);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
client_restore_enterleave_events(void)
|
client_restore_enterleave_events(void)
|
||||||
{
|
{
|
||||||
foreach(c, globalconf.clients)
|
sequence_pair_t pair;
|
||||||
{
|
|
||||||
xcb_change_window_attributes(globalconf.connection,
|
assert(globalconf.pending_enter_leave_begin.sequence != 0);
|
||||||
(*c)->window,
|
pair.begin = globalconf.pending_enter_leave_begin;
|
||||||
XCB_CW_EVENT_MASK,
|
pair.end = xcb_no_operation(globalconf.connection);
|
||||||
(const uint32_t []) { CLIENT_SELECT_INPUT_EVENT_MASK });
|
xcb_ungrab_server(globalconf.connection);
|
||||||
xcb_change_window_attributes(globalconf.connection,
|
globalconf.pending_enter_leave_begin.sequence = 0;
|
||||||
(*c)->frame_window,
|
sequence_pair_array_append(&globalconf.ignore_enter_leave_events, pair);
|
||||||
XCB_CW_EVENT_MASK,
|
|
||||||
(const uint32_t []) { FRAME_SELECT_INPUT_EVENT_MASK });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Record that a client got focus.
|
/** Record that a client got focus.
|
||||||
|
|
|
@ -297,10 +297,10 @@ static void
|
||||||
drawin_map(lua_State *L, int widx)
|
drawin_map(lua_State *L, int widx)
|
||||||
{
|
{
|
||||||
drawin_t *drawin = luaA_checkudata(L, widx, &drawin_class);
|
drawin_t *drawin = luaA_checkudata(L, widx, &drawin_class);
|
||||||
/* Activate BMA */
|
|
||||||
client_ignore_enterleave_events();
|
|
||||||
/* Apply any pending changes */
|
/* Apply any pending changes */
|
||||||
drawin_apply_moveresize(drawin);
|
drawin_apply_moveresize(drawin);
|
||||||
|
/* Activate BMA */
|
||||||
|
client_ignore_enterleave_events();
|
||||||
/* Map the drawin */
|
/* Map the drawin */
|
||||||
xcb_map_window(globalconf.connection, drawin->window);
|
xcb_map_window(globalconf.connection, drawin->window);
|
||||||
/* Deactivate BMA */
|
/* Deactivate BMA */
|
||||||
|
|
|
@ -93,8 +93,12 @@ table.insert(steps, function()
|
||||||
x = w.x + w.width - 20 - 12.5,
|
x = w.x + w.width - 20 - 12.5,
|
||||||
y = w.y + 125 + 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
|
return true
|
||||||
end)
|
end)
|
||||||
|
|
Loading…
Reference in New Issue