wmutils / opt

optional addons to wmutils
Other
114 stars 24 forks source link

wew sometimes doesn't catch an event #3

Closed joaopms closed 8 years ago

joaopms commented 9 years ago

If you move your mouse too quickly from one window to another, wew won't catch event number 7 (XCB_ENTER_NOTIFY), preventing my script from properly working.

Since it's seems that the event triggers on the window's border and I'm testing everything on a virtual machine before I do a real install, it could be because the VM is too slow, but I'm not sure about that.

CamilleScholtz commented 9 years ago

Here's the fix (that works for me): https://github.com/wmutils/opt/compare/master...onodera-punpun:master#diff-0fd277e6661666192c9be11af76b25ddL99

joaopms commented 9 years ago

@onodera-punpun It fixed it, thanks!

z3bra commented 9 years ago

Since a few commits, wew now behave properly for me, and never miss an ENTER_NOTIFY event. Whic version are you using?

Now regarding @onodera-punpun "fix". ee->detail == 0 means "Cursor crossed border from outside to in inside". In case of a xcb_leave_notify_event_t (which uses the same data structure), you'd get  ee->detail == 2. This element is the only way to differenciate ENTER for LEAVE events.

As of this explanation, your "fix" will only make wew trigger an ENTER_NOTIFY event, when it is in fact a LEAVE_NOTIFY. Which would make wew misbehave. I have no explanations as to why it hacks around your problem, but I read some code regarding this, and it seems to be the correct way "ENTER_NOTIFY" events should be handled.

joaopms commented 9 years ago

I am using the version before today's commit. Can it be because I'm running on a VM, making it unreliable?

z3bra commented 9 years ago

It might be. Which WM are you running?

À dim. août 2 00:27:44 2015 GMT+0200, João Pedro a écrit :

I am using the version before today's commit. Can it be because I'm running on a WM, making it unreliable?


Reply to this email directly or view it on GitHub: https://github.com/wmutils/opt/issues/3#issuecomment-12695850

Envoyé depuis mon Jolla

joaopms commented 9 years ago

I meant VM, not WM. Anyway, I'm using VirtualBox v4.3.28 r100309 on Windows 8.1 Pro 64 bits.

Ferdi265 commented 9 years ago

I had this happen to me as well (using today's git). Because of that, I experimented a little and found out that detail is only 2 for a transition between a window border and a window content of the same window ID. All other values of detail are actual transitions between windows (window content to other window content, window border to root window, etc) that should send an enter or leave event.

Also, the transition between window border to window content (of the same window ID, detail == 2) sends an xdg_leave_notify_event even though the transition is in the direction of the inside of the window

I made a small fork with a patch for this, here is the diff

Behavior with current master: Transitions between overlapping windows don't send enter or leave events. Transitions from and to the root window work fine. Transitions directly from the root window to the window content (e.g. by moving the mouse very fast) also don't work.

Behavior with my fork: All transitions except window border to/from window content (of the same window ID) send leave and enter events.

Ferdi265 commented 9 years ago

Here's an image illustrating the issue:

I moved my mouse cursor along the white line. On the left, you can see the output of a modified wew (modified to print out the response_type, detail, and event (contains wid of the window) properties instead of only response_type and wid).

As you can see, the only times that current master would have detected an enter/leave event are the start, the point where it changes directions and goes back, and the end. All these have in common that these are transitions to and from the root window, which is what detail == 0 means.

Event description (in order):

response_type: ENTER (7) detail: 0 wid: 0x00a00009 Enter border of the first window (from root) response_type: LEAVE (8) detail: 2 wid: 0x00a00009 Leave border of the first window (to content) response_type: ENTER (7) detail: 2 wid: 0x00a00009 Enter border of the first window (from content) response_type: LEAVE (8) detail: 3 wid: 0x00a00009 Leave border of the first window (to content of the second window) response_type: ENTER (7) detail: 4 wid: 0x00800009 Enter content of the second window (from border of the first window) response_type: ENTER (7) detail: 2 wid: 0x00800009 Enter border of the second window (from content) response_type: LEAVE (8) detail: 0 wid: 0x00800009 Leave border of the second window (to root) response_type: ENTER (7) detail: 0 wid: 0x00800009 Enter border of the second window (from root) response_type: LEAVE (8) detail: 2 wid: 0x00800009 Leave border of the second window (to content) response_type: LEAVE (8) detail: 4 wid: 0x00800009 Leave content of the second window (to border of the first window) response_type: ENTER (7) detail: 3 wid: 0x00800009 Enter border of the first window (from content of the second window) response_type: LEAVE (8) detail: 2 wid: 0x00800009 Leave border of the first window (to content) response_type: ENTER (7) detail: 2 wid: 0x00800009 Leave border of the first window (to content) response_type: LEAVE (8) detail: 0 wid: 0x00800009 Leave border of the first window (to root)

z3bra commented 9 years ago

Wow, that is an awesome job you did there to figure out what the detail is. I tried to figure it out myself, but it seems that I failed miserably.

Thank you for sorting this out, I'll update wew's behavior to include this.

À sam. août 8 18:48:50 2015 GMT+0200, Ferdi265 a écrit :

Here's an image illustrating the issue:

I moved my mouse cursor along the white line. On the left, you can see the output of a modified wew (modified to print out the response_type, detail, and event (contains wid of the window) properties instead of only response_type and wid).

As you can see, the only times that current master would have detected an enter/leave event are the start, the point where it changes directions and goes back, and the end. All these have in common that these are transitions to and from the root window, which is what detail == 0 means.

Event description (in order):

response_type: ENTER (7) detail: 0 wid: 0x00a00009 Enter border of the first window (from root) response_type: LEAVE (8) detail: 2 wid: 0x00a00009 Leave border of the first window (to content) response_type: ENTER (7) detail: 2 wid: 0x00a00009 Enter border of the first window (from content) response_type: LEAVE (8) detail: 3 wid: 0x00a00009 Leave border of the first window (to content of the second window) response_type: ENTER (7) detail: 4 wid: 0x00800009 Enter content of the second window (from border of the first window) response_type: ENTER (7) detail: 2 wid: 0x00800009 Enter border of the second window (from content) response_type: LEAVE (8) detail: 0 wid: 0x00800009 Leave border of the second window (to root) response_type: ENTER (7) detail: 0 wid: 0x00800009 Enter border of the second window (from root) response_type: LEAVE (8) detail: 2 wid: 0x00800009 Leave border of the second window (to content) response_type: LEAVE (8) detail: 4 wid: 0x00800009 Leave content of the second window (to border of the first window) response_type: ENTER (7) detail: 3 wid: 0x00800009 Enter border of the first window (from content of the second window) response_type: LEAVE (8) detail: 2 wid: 0x00800009 Leave border of the first window (to content) response_type: ENTER (7) detail: 2 wid: 0x00800009 Leave border of the first window (to content) response_type: LEAVE (8) detail: 0 wid: 0x00800009 Leave border of the first window (to root)


Reply to this email directly or view it on GitHub: https://github.com/wmutils/opt/issues/3#issuecomment-12901128

Envoyé depuis mon Jolla

z3bra commented 9 years ago

I just read your diff, but couldn't test it. firs it means the ENTER event will be sent twice each time the cursor enters a window? (enters border AND enters content). If yes, then it bother me as it should only trigger it once. For the user, the cursor only enters the "window", so there shouldn't be 2 events. I'll troubleshoot this.

Also, c++ comments are forbidden by c99 standards. Prefer block comments instead.

Good.job otherwise, it really helps as wew will niw be able to notice when entering a window from another window, which is something that I couldn't figure out how to do.

Ferdi265 commented 9 years ago

It seems that the border is kind of a sub-window thing (don't really know how Xlib and xcb work, so this is just guesswork).

Interestingly the border is treated as if it were just another window (with the exception of having special detail values for events). when you transition from the border to the content, you don't enter the content, you "leave the border". I think it is quite weird myself, but I guess it could kind of be used to implement resize-when-dragging-on-border-like things.

Also: figuring this out was a few hours of work, I was confused too at first, but then I tried to map every event to a mouse action until I figured it out.

Thanks for the tip with the comments. I'll update my fork and submit a PR.

Ferdi265 commented 9 years ago

To clarify: (only tested with windows that have borders, setting window border to 0px behaves the same way, but I don't know how windows that never had borders in the first place behave. From my research, they should behave correctly though)

When the mouse enters the window (from the root window, passing the border), the following happens in order:

The mouse enters the border, an ENTER event with detail 0 is sent. The mouse enters the content (i.e. leaves the border), a LEAVE event with detail 2 is sent.

this means, when the mouse enters a window from the root window, both a leave and an enter event are sent. This is different with overlapping windows.

Assume W1 and W2 are windows, the mouse is in W1s content, and W1 overlaps W2 (W1 is on top). The mouse enters W1s border, an ENTER event with detail 2 is sent for W1. The mouse leaves W1s border, a LEAVE event with detail 3 is sent for W1. Simultaneously, the mouse enters W2s content, an ENTER event with detail 4 is sent for W2.

This means that if events with detail 2 (border events) are ignored, an enter or leave event will be sent for every actual window enter or leave. There will not be duplicate events, and situations like fast moving mice (or nonexistant borders) are handled correctly.

If you ignore detail 2 events, the previous examples (and the wew output) change to this:

Example Nr.1: An ENTER event is sent for W1

Example Nr.2: A LEAVE event is sent for W1. Simultaneously, an ENTER event is sent for W2.

z3bra commented 9 years ago

The borders are special from the X POV. They're not really windows, but they are still an "object" on their own, which is why X makes the difference between a window and its border.

From wew's POV, I think that entering a window should mean both crossing a window's border from outside to inside, or entering content. It should not report 2 'ENTER' events when the cursor enters a window. That would be both confusing for the user, and useless (if not annoying) when parsing events. So yeah, I gave it a try, and simply ignoring events with detail:2 is good enough. So the patch is as easy as replacing ee->detail == 0 to ee->detail ^ 2

I don't know how much you care about having your nick listed in the commiters, so if you want to provide a pull-request, that's ok. Otherwise I can just push the changes I just made. It's up to you.

z3bra commented 9 years ago

I tried to document the details from what I could reproduce, without looking at your explanations to avoid being biaised. I couldn't reproduce some of the events though, so I just left them as is. Here is the explanation I found:

/*
 * the "detail" value will provide informations on HOW the enter/leave
 * event was triggered.
 *
 * ENTER:
 * + detail 0: root -> border self
 * + detail 1: cursor grabbed -> content self
 * + detail 2: border self -> content self
 * + detail 3: ???
 * + detail 4: border self -> content other
 *
 * LEAVE:
 * + detail 0: border self -> root
 * + detail 1: ???
 * + detail 2: border self -> content self
 * + detail 3: border self -> content other
 * + detail 4: ???
 *
 * Basically, ignoring detail 2 will match all events where we enter a
 * window without doubling the ENTER/LEAVE event (eg, enter border +
 * enter content)
 */

For the ENTER detail 1, it occured when I had the mouse cursor grabbed by an application, and I release it within a window. It doesn't occur when you leave the window grabbed and release it outside (or at least, I couldn't reproduce it).

He still believe this event is a pain to deal with, and won't change the function name for any reason, haha.

Ferdi265 commented 9 years ago

We're getting closer and closer to knowing how exactly this event works.

My POV of how I think detail 1 works:

The way mouse input in X works, it polls the mouse for a delta and moves the mouse accordingly. If the delta is high enough that it doesn't actually cross the border, but "teleports" in, that is a transition root -> content. This always seems to have detail 1. It seems that cursor grabbed might be similar: When it is ungrabbed, it "teleports" somewhere. This could probably reproduced more easily with an absolute pointing device (i.e. tablet).

Leave detail 1 has happenes to me by doing the opposite: fling the mouse (so fast that the delta is high enough), that it leaves the window without transitioning over the border. When I get home, I'll test this with wmp (warp mouse pointer) as that seems to be the number 1 objective testing tool for this problem.

Leave detail 3 also seems to happen for me with border self -> border other (tested with huge borders and aligning windows so borders overlap) useful testing tool here is chwb So in summary: leave detail 3 is border self -> (border l content) other

Enter detail 3 is the same but the other way round

(border l content) other -> border self

For detail 4 it's the same, but you replace border self with content self:

Leave detail 4: content self -> (border l content) other

Enter detail 4: (border l content) other -> content self

Anyway, could you provide a screenshot like mibe (testing windows, event log, description of events).

I'll attach a wew patch like the one seen in my screenshot for testing purposes.

(Also, motherfuckingenterevent() seems to fit even better now, as we seem to be just beginning to understand how f*cked up this whole thing is)

Once we finish documenting how this works we should push it upstream to xcb as it seems to still be marked as NOT YET DOCUMENTED on the manpage for xcb_enter_notify_event_t and xcb_leave_notify_event_t

As a final note: Once this gets resolved, I'd want to either do this with a PR, or if not, at least be mentioned in the commit message (not in the headline, that wouldn't make any sense).

I love your scientific approach to this, so to make this a bit more objective, we should start to create test cases and continuously try to verify or disprove each others theories until we both agree :)

z3bra commented 9 years ago

I've been testing a few things, and your idea about detail 1 seems to be the good one. I didn't bother testing LEAVE events, as I simply find no use for them right now.

I experimented ENTER events a bit, and here is what I found:

ENTER:0 - root -> border
ENTER:1 - root -> content
ENTER:2 - content -> border
ENTER:3 - self -> above
ENTER:4 - self -> below

above/below refering to the stacking order. I made a quick video to illustrate my theory: http://raw.z3bra.org/dev/random/wew-details.webm If I'm right, this might introduce a new "bug" (more like unwanted behavior) where wew will trigger an ENTER event when you have 2 windows under your cursor, and then teleport the first one elsewhere.

This is what I show at the end of my video, where the cursor is on the top window, and then you move this window so that the cursor focus the window below. an ENTER:4 event is triggered.

We'll have to figure out what the "best" behavior is.

Ferdi265 commented 9 years ago

That's what I've been noticing too when testing things. What do you think the behavior should be? Because logically you are technically leaving the window when you move it somewhere else. and if it didn't send an enter event for this situation, it would still send a leave event for when you leave that window, even though an enter event for that window would never have been sent.

This patch seems to be a very tricky situation, as it is clearly broken in current master, and the fix seems logical, but seems to add confusing behavior, which might break people's setups.

Ferdi265 commented 9 years ago

Ok, just tested this: detail 3 and 4 don't neccessarily have to do with above or below.

See this screenshot (I don't have video recording working yet, ffmpeg gives me only weird parts of my screen in really bad quality, sadly. I'll have to play with the arguments a bit)

Here, I've disabled my autofocus on window enter script (killall event_watcher). My mouse was in the bottom right window, and then I wmp'd it up into the other window and down again a few times.

This means, that every other enter event should be one for "above", and the others for "below", right?

It seems that detail 4 is for is specifically for from other window content or border to this window's content. In a usual setup, this would mean that we are entering a window below the current one, as the only way to directly enter a window without crossing the border is if the current window is above the entered window, but as soon as you add absolute pointing devices (tablets) or mouse warping, this assumption breaks down, because we can enter every visible part of every window from anywhere.

I'll add similar test cases for detail 3 after I finish my testing on it

Next test case, this time for detail 3. Ugly as hell, but it's easier with huge-ass borders:

This is essentially the same as the last one, but the mouse is positioned on the border. Only detail 3 events are sent, which are, from what I see always sent if you transition from a window border to any part of another window. When I enter a window above the window the cursor is currently in, which is overlapping the window (visible in my first test case), I enter its border first, which sends a detail 3 event. If you also look at the leave events, you'll see a leave detail 4, as we leave directly from the content to something different.

z3bra commented 9 years ago

I must admit having a few difficulties to understand your point here. Using still images probably don't help much.

Would you be avail on IRC to discuss it directly? I'll be in #wmutils on irc.iotek.org fir the next hour

z3bra commented 9 years ago

I did some further testing after reading your comment carefully, and you were right, it has nothing to do with the stacking order. From what I could figure out, here is the updated list of details for the ENTER event:

ENTER:0 - root -> border self
ENTER:1 - root -> content self
ENTER:2 - content self -> border self
ENTER:3 - self -> border other
ENTER:4 - self -> content other

Is that what you noticed too?

z3bra commented 9 years ago

Fuck. When I move the cursor from urxvt's border, to dwb's content, I get detail == 3. This is driving me crazy...

Ferdi265 commented 9 years ago

Sorry for being silent for so long, but I didn't find time to do any further research about this.

What I did find out is that xev seems to have names for the detail property, which could further hint to the actual meaning of the detail property.

z3bra commented 9 years ago

I'm glad to see you back! And with a good hint!! I tried to play with it a bit but I must say I'm still confused as for the output of xev. Many events/details seems to be missing

Ferdi265 commented 9 years ago

Yeah, I still have to get back into the flow (also, install wmutils so I can actually test stuff). I don't get some stuff that xev outputs either, but it might be worth a try.

I also have working ffmpeg recording now, so there's that. Only problem is that school's picking up again, and there's a lot to do, but I'll try to get a good look on this problem, so we can actually fix it soon-ish.

Ferdi265 commented 8 years ago

So, testing this further, testing scripts:

I made a script that spawns a few urxvt windows in specific positions and teleports the mouse cursor into them with wmp, all while having a specially modified version of wew running, that displays debug output for the enter and leave events. Source is available on my fork in branch wewtest.

The goal of this is to have tests that others can run and confirm, without having to think about it the same way as I do. This avoids bias, while confirming true observations.

The script:

First ./test

#!/bin/bash

# tested with border-width 2 in focus.sh

# expects ./wewtest to be (a symlink to) my modified wew
# expects ./urxvt-wewtest to be (a symlink to) urxvt
# expects ./empty to exist

# adjust accordingly
screen_x=1280
screen_y=1024

# expects newly created windows to stay where they were created
spawn-urxvt() {
    ./urxvt-wewtest -geometry $1 -e './empty' &
}

echo 'Moving mouse to known location (0, 0)'
wmp -a 0 0

echo 'Spawning urxvt windows'

spawn-urxvt '80x10-20+20'
spawn-urxvt '80x10-20+200'

echo 'Starting wew'
# listen for enter and leave events only
./wewtest -m 48 &

sleep 1

echo 'Testing root -> window content'
wmp -a $((screen_x - 30)) 30
sleep 1

echo 'Testing window content -> window content'
wmp -a $((screen_x - 30)) 210
sleep 1

echo 'Testing window content -> root'
wmp -a $((screen_x - 30)) 390
sleep 1

echo 'Test completed'

sleep 1

echo 'Killing processes'
killall wewtest
killall urxvt-wewtest

and ./empty

#!/bin/bash

while true; do
    sleep 10
done

My results:

z3bra commented 8 years ago

This might help too: https://tronche.com/gui/x/xlib/events/window-entry-exit/

Gonna take a closer look at this tomorrow

z3bra commented 8 years ago

that too: http://menehune.opt.wfu.edu/Kokua/Irix_6.5.21_doc_cd/usr/share/Insight/library/SGI_bookshelves/SGI_Developer/books/XLib_PG/sgi_html/re10.html

Ferdi265 commented 8 years ago

From the second link:

detail

The value of the detail member depends on the hierarchical relationship between the origin and destination windows and the direction of pointer transfer. Determining which windows receive events > and with which detail members is quite complicated. This topic is described in the next section.

What then follows is the section Virtual Crossing and the detail Member.

The possible values for detail are NotifyAncestor, NotifyVirtual, NotifyInferior, NotifyNonlinear, and NotifyNonlinearVirtual. This maps nicely with the 5 possible values I (and possibly we) have observed in testing.

My documentation snippet from the PR:

/**
  * xcb_enter_notify_event_t->detail and
  * xcb_leave_notify_event_t->detail Documentation:
  * Legend:
  *     self .... wid in ee->event
  *     other ... other wid
  *     root .... root window
  * ee->response_type == 7 (enter):
  *     e->detail == 0:
  *         root -> border self
  *     e->detail == 1:
  *         root -> content self
  *     e->detail == 2:
  *         content self -> border self
  *     e->detail == 3:
  *         other -> border self
  *     e->detail == 4:
  *         other -> content self
  * ee->response_type == 8 (leave):
  *     e->detail == 0:
  *         border self -> root
  *     e->detail == 1:
  *         content self -> root
  *     e->detail == 2:
  *         border self -> content self
  *     e->detail == 3:
  *         border self -> other
  *     e->detail == 4:
  *         content self -> other
**/

The only problem here is, that we don't know for sure which of these names maps to which of the possible detail values of 0 to 4. If you take them in the order specified in the first link, you get something that seems to make sense, but we can't take that for granted, as the second link lists a different name order.

These names look like something that would be defined as a constant in an XCB header file. It might be worth looking into that to get the definitive order.

Ferdi265 commented 8 years ago

I found it!

All the XCB constants are defined in <xcb/xproto.h> which is included from <xcb/xcb.h>.

In there, we have an enum called xcb_notify_detail_t, with all mappings we observed and more.

typedef enum xcb_notify_detail_t {
    XCB_NOTIFY_DETAIL_ANCESTOR = 0,
    XCB_NOTIFY_DETAIL_VIRTUAL = 1,
    XCB_NOTIFY_DETAIL_INFERIOR = 2,
    XCB_NOTIFY_DETAIL_NONLINEAR = 3,
    XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL = 4,
    XCB_NOTIFY_DETAIL_POINTER = 5,
    XCB_NOTIFY_DETAIL_POINTER_ROOT = 6,
    XCB_NOTIFY_DETAIL_NONE = 7
} xcb_notify_detail_t;

As you can see, the order from the first link is, in fact, correct.

With this knowledge I hope I'll understand the section on the detail value from the second link.

Ferdi265 commented 8 years ago

From what I've read in the second link, these are my insights into the actual window hierarchy:

Example (indented further == child):

ROOT
    urxvt #1 (whole window, including border)
        content (implemented as a child window of urxvt #1)
    urxvt #2 (whole window, including border)
        content (implemented as a child window of urxvt #2)

For now, I'll discuss only enter events:

Now, if we transition from ROOT to urxvt #1 (that is the border), urxvt #1 gets an enter event with XCB_NOTIFY_DETAIL_ANCESTOR.

If we transition from ROOT to urxvt #1.content directly, without passing urxvt #1's border (via grabbing, wmp, or quick mouse movement), this is a transition from a parent to a child of its child. Therefore, all windows in between (including urxvt #1) get an enter event with XCB_NOTIFY_DETAIL_VIRTUAL.

Transitions between the window's content, urxvt #1.content and the window itself, urxvt #1 give an enter event with XCB_NOTIFY_DETAIL_INFERIOR because the pointer came from a child window.

When transitioning between windows not directly children of one another, they both get events with XCB_NOTIFY_DETAIL_NONLINEAR (one gets an enter and one gets a leave event). if the movement initiated from a child or ended in a child of the windows, the parent of that window receives an event with XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL (e.g. urxvt #1.content to urxvt #2 (border) gives urxvt #1 a leave event with XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL, and urxvt #2 an enter event with XCB_NOTIFY_DETAIL_NONLINEAR)

Ferdi265 commented 8 years ago

A possible solution to the event confusion would be to ignore events of type XCB_NOTIFY_DETAIL_INFERIOR on all windows because those are enter and leave events concering child windows of that window.

As you can see, the value of XCB_NOTIFY_DETAIL_INFERIOR is 2.

Thank you for these two links. They are like a gold mine worth of information on this. Great job!

EDIT: I just noticed that ignoring XCB_NOTIFY_DETAIL_INFERIOR can in some cases miss events from some windows. Notably, these are child windows that take focus, in which case you WOULD want to have enter and leave events between windows and their children. Notable examples are firefox context menus and the hamburger menu. (not thoroughly tested. Based on earlier examinations. Should be re-tested)

z3bra commented 8 years ago

I ended up finding a detailed explaination here: http://tronche.com/gui/x/xlib/events/input-focus/normal-and-grabbed.html which helped me sorting it all out. Here is a table that explains everything:

ENTER:
------

+-------------------------------------+-------+-----------------+------------------+-----------------+
| EVENT_NAME                          | VALUE | CURSOR_MOVEMENT | WINDOW_HIERARCHY | EVENT_RAISED_ON |
+-------------------------------------+-------+-----------------+------------------+-----------------+
| XCB_NOTIFY_DETAIL_ANCESTOR          |     0 | A --> B         | A < B            | B               |
| XCB_NOTIFY_DETAIL_VIRTUAL           |     1 | A <-> C         | A > B > C        | B               |
| XCB_NOTIFY_DETAIL_INFERIOR          |     2 | A --> B         | B > A            | B               |
| XCB_NOTIFY_DETAIL_NONLINEAR         |     3 | A --> B         | C > A and C > B  | B               |
| XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL |     4 | A --> B         | C > C1 > A and   | C1              |
|                                     |       |                 | C > C2 > B       | C2              |
| XCB_NOTIFY_DETAIL_POINTER           |     5 | * --> A         | *                | A               |
| XCB_NOTIFY_DETAIL_POINTER_ROOT      |     6 | * --> A         | *                | A, ROOT (?)     |
| XCB_NOTIFY_DETAIL_NONE              |     7 | discard event   |                  |                 |
+-------------------------------------+-------+-----------------+------------------+-----------------+

I'm not ENTIRELY sure about the XCB_NOTIFY_DETAIL_POINTER_ROOT event though. But I don't really mind for now.

So in the end, I think we need wew to raise all events with detail XCB_NOTIFY_DETAIL_POINTER. Whenever the cursor enter/leaves a window, or all events that would happen in NORMAL or UNGRAB mode. This is the case which will trigger the sanest ENTER/LEAVE events.

I tested this "new" version of wew, and it seems to work rather nicely. I'll push in a branch named "notify-detail". Tell me what you think about it.

Ferdi265 commented 8 years ago

The only problem is that, again, this new version of wew outputs both an enter and a leave event for every window entered. (1: Entering the window, 2: leaving the window to the content child window)

This properly represents the way X handles this, but makes this event almost useless for general use in scripts. This kind of event should either not be included or the wew output should contain detail values

z3bra commented 8 years ago

I get your point. Let me think about it

z3bra commented 8 years ago

Seems that you were right: ignoring XCB_NOTIFY_DETAIL_INFERIOR gives a better result in our case.

Gonna push it a test for a while. Thanks a lot!

Ferdi265 commented 8 years ago

Sure thing :)

z3bra commented 8 years ago

Just found an annoyance with this version: wew-notify_inferior

The focus is given to the underlying window (A) when you move the first window (B) so that the pointer is above window A. In the video, I try to move the above window to the bottom of the screen. But when I reach the point where the pointer is above the other window, focus is given to it and I start moving the other window. That's REALLY frustrating :P

EDIT: added a GIF so it's stored locally.

Ferdi265 commented 8 years ago

Known annoyance.

This is a consequence of the fact that moving something below the curser gives an "enter" event in X. The same thing happens as well with the old version of wew if you move the windows in small enough steps or have big enough borders or just have bad luck: In that case the cursor lands on the window border and triggers a focus change.

A workaround to this is to synchronize some wmutils scripts to "disable" autofocus for the duration of a window movement and then "reenabling" it.

On a side note: Your desktop looks stunning everytime I see it, and it's different every time

z3bra commented 8 years ago

I think we can find a solution around it. By digging those DETAIL_NOTIFY_POINTER maybe?

À mar. nov. 17 20:55:09 2015 GMT+0100, Ferdi265 a écrit :

Known annoyance.

This is a consequence of the fact that moving something below the curser gives an "enter" event in X. The same thing happens as well with the old version of wew if you move the windows in small enough steps or have big enough borders or just have bad luck: In that case the cursor lands on the window border and triggers a focus change.

A workaround to this is to synchronize some wmutils scripts to "disable" autofocus for the duration of a window movement and then "reenabling" it.


Reply to this email directly or view it on GitHub: https://github.com/wmutils/opt/issues/3#issuecomment-15748740

Envoyé depuis mon Jolla

Ferdi265 commented 8 years ago

I've never seen an XCB_NOTIFY_DETAIL_POINTER happen in the wild, though.

Do you by any chance have a test case with which you can reliably reproduce such an event?

z3bra commented 8 years ago

Not yet :/

z3bra commented 8 years ago

Fixed by: 8754fc9ddcf31d99f79e214088389eb0af3e2966