New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Huge mouse-click delays #1107
Comments
|
Could you try running awesome with Such messages (with times of "several seconds") would really point towards awesome. |
|
Hey, I am already running with The Here is the video (250Mb!): http://scratch.madduck.net/.tmp__20160921_133528.mp4 |
|
Thanks for bisecting this. @psychon We could just revert the commit and move on? I am unconvinced this feature is improving performance by much, does it? |
|
I'd like to know why it is slow. How many clients do you have open for this to become slow? Iterating over all clients should be fast. My guess would then be that diff --git a/globalconf.h b/globalconf.h
index 877be22..124d157 100644
--- a/globalconf.h
+++ b/globalconf.h
@@ -180,6 +180,7 @@ typedef struct
uint32_t preferred_icon_size;
/** Cached wallpaper information */
cairo_surface_t *wallpaper;
+ bool need_client_geometry_refresh;
} awesome_t;
extern awesome_t globalconf;
diff --git a/objects/client.c b/objects/client.c
index e561aae..91a431f 100644
--- a/objects/client.c
+++ b/objects/client.c
@@ -1138,6 +1138,9 @@ client_border_refresh(void)
static void
client_geometry_refresh(void)
{
+ if (!globalconf.need_client_geometry_refresh)
+ return;
+ globalconf.need_client_geometry_refresh = false;
client_ignore_enterleave_events();
foreach(_c, globalconf.clients)
{
@@ -1555,6 +1558,8 @@ client_resize_do(client_t *c, area_t geometry)
{
lua_State *L = globalconf_get_lua_State();
+ globalconf.need_client_geometry_refresh = true;
+
screen_t *new_screen = c->screen;
if(!screen_area_in_screen(new_screen, geometry))
new_screen = screen_getbycoord(geometry.x, geometry.y);Also, to check if the slow part really is diff --git a/objects/client.c b/objects/client.c
index e561aae..85426f7 100644
--- a/objects/client.c
+++ b/objects/client.c
@@ -1003,33 +1003,11 @@ client_ban(client_t *c)
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) });
- }
}
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 });
- }
}
/** Record that a client got focus.Neither of these patches are meant for merging. This is just for figuring out what the problem is. |
|
Hey @psychon, thanks for your continued work on this! I am very happy I can try to help by testing your patches. Both patches (tried individually) make the problem go away when applied on top of the current master HEAD. As per your initial question: I can have dozens of clients open without the problem, but if any of Firefox, Thunderbird or Chromium are open (even on an invisible tag), then the delays come back. |
This commit makes the function only call client_ignore_enterleave_events() when it actually has to. Since we expect that most of the time, no client's geometry is changed, this means that most of the time this function is not called. Fixes: awesomeWM#1107 Signed-off-by: Uli Schlachter <psychon@znc.in>
|
Thanks for testing. I got another patch. I'd be really surprised if it didn't work, but better be safe than sorry. ;-) diff --git a/objects/client.c b/objects/client.c
index e561aae..bdb3726 100644
--- a/objects/client.c
+++ b/objects/client.c
@@ -1138,7 +1138,7 @@ client_border_refresh(void)
static void
client_geometry_refresh(void)
{
- client_ignore_enterleave_events();
+ bool ignored_enterleave = false;
foreach(_c, globalconf.clients)
{
client_t *c = *_c;
@@ -1164,6 +1164,11 @@ client_geometry_refresh(void)
&& AREA_EQUAL(real_geometry, c->x11_client_geometry))
continue;
+ if (!ignored_enterleave) {
+ client_ignore_enterleave_events();
+ ignored_enterleave = true;
+ }
+
xcb_configure_window(globalconf.connection, c->frame_window,
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
(uint32_t[]) { geometry.x, geometry.y, geometry.width, geometry.height });
@@ -1177,7 +1182,8 @@ client_geometry_refresh(void)
/* ICCCM 4.2.3 says something else, but Java always needs this... */
client_send_configure(c);
}
- client_restore_enterleave_events();
+ if (ignored_enterleave)
+ client_restore_enterleave_events();
}
voidThanks a lot for testing these patches! |
There are some situations where we do things that can make the mouse pointer enter another window. We do not want to react to these "self inflicted" mouse enter and leave events, because they aren't "real" (= generated by the user). Before this commit, this is done by going through all windows and toggling the "please send us enter and leave events"-bit on them. This becomes slower when many windows are visible and floods the server with requests. This commit changes this to a constant-time logic. Each event contains the sequence number of the last request that the X11 server handled. Thus, we just remember the right sequence numbers and ignore any events that comes in whose sequence number falls into the ignored range. In detail, we keep a list of "begin" and "end" sequence numbers and ignore any enter and leave events that fall in this range. If we get any event with a sequence number higher than "end", we remove this pair from the list, since it is no longer needed. To generate these pairs, we use a GrabServer request in client_ignore_enterleave_events(). This gives us a sequence number and makes sure that nothing else besides us can cause events. The server is ours! In client_restore_enterleave_events(), we first do a NoOperation request to generate the sequence number for the end of the pair and then do UngrabServer. Any event that is generated after UngrabServer will have at least the sequence number of the UngrabServer request and thus no longer fails between begin and end. Fixes: awesomeWM#1107 Signed-off-by: Uli Schlachter <psychon@znc.in>
|
I replied at #1117… |
This commit makes the function only call client_ignore_enterleave_events() when it actually has to. Since we expect that most of the time, no client's geometry is changed, this means that most of the time this function is not called. Fixes: awesomeWM#1107 Signed-off-by: Uli Schlachter <psychon@znc.in>
There are some situations where we do things that can make the mouse pointer enter another window. We do not want to react to these "self inflicted" mouse enter and leave events, because they aren't "real" (= generated by the user). Before this commit, this is done by going through all windows and toggling the "please send us enter and leave events"-bit on them. This becomes slower when many windows are visible and floods the server with requests. This commit changes this to a constant-time logic. Each event contains the sequence number of the last request that the X11 server handled. Thus, we just remember the right sequence numbers and ignore any events that comes in whose sequence number falls into the ignored range. In detail, we keep a list of "begin" and "end" sequence numbers and ignore any enter and leave events that fall in this range. If we get any event with a sequence number higher than "end", we remove this pair from the list, since it is no longer needed. To generate these pairs, we use a GrabServer request in client_ignore_enterleave_events(). This gives us a sequence number and makes sure that nothing else besides us can cause events. The server is ours! In client_restore_enterleave_events(), we first do a NoOperation request to generate the sequence number for the end of the pair and then do UngrabServer. Any event that is generated after UngrabServer will have at least the sequence number of the UngrabServer request and thus no longer fails between begin and end. Fixes: awesomeWM#1107 Signed-off-by: Uli Schlachter <psychon@znc.in>
Output of✔
awesome --version:awesome v3.5.2-2001-gb4d6bfa (The Fox)
• Compiled against Lua 5.1.5 (running with Lua 5.1)
• D-Bus support:
How to reproduce the issue:
Start it, use the mouse a bit, observe.
Actual result:
Between click of a mouse button and reaction in X client, there's an increasing delay up to several seconds.
Expected result:
Instantaneous reaction.
Here's why I think this is a problem with awesome:
In short, because if I replace awesome with fvwm2, the problems go away. If I replace fvwm with awesome again, the problem comes back.
The issue appears with evdev, as well as libinput, with the internal trackpad, as well as an external mouse. xev and evemu-record both see the event immediately. All clients experience the delay, no matter what framework, including pure xterm. Curiously, I don't know why xev (which has its own window) doesn't experience the delay, but I suppose it hooks into the driver or hardware much higher up. Neither X server nor any drivers were updated before the problem appeared, but the issues did start in the wake up replacing awesom 3.4.15 with current Git master, and they exist too with stock rc.lua.
I'll try to record a video as soon as I am back in a work environment.
The text was updated successfully, but these errors were encountered: