Repository: qtile/qtile

Issue:
Mouse click is not working on browser's auto suggestions
A mouse click is not working in most of the browser suggestions. If i click on the address bar and hit any suggestions it is working fine but when I fill a forum, log in or search for anything in sites then I have to do it with the keyboard's navigation key.

**Bug:**
[https://giphy.com/gifs/C1xq9ILSfXuzsPdRmF](https://giphy.com/gifs/C1xq9ILSfXuzsPdRmF)

**Qtile version :**  _0.18.1.dev0+g8e7ecc0a.d20210719_

**Configuration:** [https://www.dropbox.com/s/6hdq7mugrsthqud/config.py?dl=0](https://www.dropbox.com/s/6hdq7mugrsthqud/config.py?dl=0)



Discussion:
What browser?

Can you post the debug log output from the event?
> What browser?
> 
> Can you post the debug log output from the event?

I don't think it's a browser issue cause I've DWM install along with the Qtile and it's working there
You're right, but only by knowing which browser is experiencing 
symptoms under Qtile can we track what we are handling correctly.

On Fri, Sep 3 2021 at 03:22:05 AM -0700, Zexu Knub 
***@***.***> wrote:
>> What browser?
>> 
>> Can you post the debug log output from the event?
>> 
> I don't think it's a browser issue cause I've DWM install along with 
> the Qtile and it's working there
> 
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub, or unsubscribe.
> Triage notifications on the go with GitHub Mobile for iOS or Android.
> 



> You're right, but only by knowing which browser is experiencing symptoms under Qtile can we track what we are handling correctly.
> […](#)
> On Fri, Sep 3 2021 at 03:22:05 AM -0700, Zexu Knub ***@***.***> wrote: > What browser? > > Can you post the debug log output from the event? > I don't think it's a browser issue cause I've DWM install along with the Qtile and it's working there — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android.

I logged the mouse click even but it's way too long. Also I've been having this issue in both vivaldi & brave browser so i think the bug is active on the chromium base.
Yeah, the debug output is very verbose.  No worries - I can reproduce locally. We've had a similar issue before, see #2404. A workaround is to use `--disable-features=SendMouseLeaveEvents` as a flag to the program. This seems to work for me for `chromium` and it might work for others. This is sad to see this appear again. Will have to investigate.
It seems to work fine for me when the window is tiled and is the only window in the tiled layout. If I tile another window or make the window float, then it  fails again. Do you see the same?
> Yeah, the debug output is very verbose. No worries - I can reproduce locally. We've had a similar issue before, see #2404. A workaround is to use `--disable-features=SendMouseLeaveEvents` as a flag to the program. This seems to work for me for `chromium` and it might work for others. This is sad to see this appear again. Will have to investigate.

Ohh okay i'm glad to know that i'm not the only one who's having this issue. Btw i love your Qtile rice it's really cool.
> It seems to work fine for me when the window is tiled and is the only window in the tiled layout. If I tile another window or make the window float, then it fails again. Do you see the same?

In my case it's only working when i'm switching window to fullscreen mode.

Resolving patch:
diff --git a/libqtile/backend/x11/window.py b/libqtile/backend/x11/window.py
--- a/libqtile/backend/x11/window.py
+++ b/libqtile/backend/x11/window.py
@@ -764,6 +764,29 @@ def _reset_mask(self):
             eventmask=self._window_mask
         )
 
+    def _grab_click(self):
+        # Grab button 1 to focus upon click when unfocussed
+        for amask in self.qtile.core._auto_modmasks():
+            self.qtile.core.conn.conn.core.GrabButton(
+                True,
+                self.window.wid,
+                EventMask.ButtonPress,
+                xcffib.xproto.GrabMode.Sync,
+                xcffib.xproto.GrabMode.Async,
+                xcffib.xproto.Atom._None,
+                xcffib.xproto.Atom._None,
+                1,
+                amask,
+            )
+
+    def _ungrab_click(self):
+        # Ungrab button 1 when focussed
+        self.qtile.core.conn.conn.core.UngrabButton(
+            xcffib.xproto.Atom.Any,
+            self.window.wid,
+            xcffib.xproto.ModMask.Any,
+        )
+
     def get_pid(self):
         return self.window.get_net_wm_pid()
 
@@ -967,7 +990,14 @@ def focus(self, warp: bool) -> None:
                 state.remove(atom)
                 self.window.set_property('_NET_WM_STATE', state)
 
+        # re-grab button events on the previously focussed window
+        old = self.qtile.core._root.get_property("_NET_ACTIVE_WINDOW", 'WINDOW', unpack=int)
+        if old and old[0] in self.qtile.windows_map:
+            old_win = self.qtile.windows_map[old[0]]
+            if not isinstance(old_win, base.Internal):
+                old_win._grab_click()
         self.qtile.core._root.set_property("_NET_ACTIVE_WINDOW", self.window.wid)
+        self._ungrab_click()
 
         if self.group:
             self.group.current_window = self
@@ -1112,20 +1142,7 @@ def __init__(self, win, qtile, screen,
         self.place(self.x, self.y, width or self.width, height or self.height, 0, 0)
         self.unhide()
         self.update_strut()
-
-        # Grab button 1 to focus upon click
-        for amask in self.qtile.core._auto_modmasks():
-            self.qtile.core.conn.conn.core.GrabButton(
-                True,
-                self.window.wid,
-                EventMask.ButtonPress,
-                xcffib.xproto.GrabMode.Sync,
-                xcffib.xproto.GrabMode.Async,
-                xcffib.xproto.Atom._None,
-                xcffib.xproto.Atom._None,
-                1,
-                amask,
-            )
+        self._grab_click()
 
     def handle_ConfigureRequest(self, e):  # noqa: N802
         cw = xcffib.xproto.ConfigWindow
@@ -1224,20 +1241,7 @@ def __init__(self, window, qtile):
         # add window to the save-set, so it gets mapped when qtile dies
         qtile.core.conn.conn.core.ChangeSaveSet(SetMode.Insert, self.window.wid)
         self.update_wm_net_icon()
-
-        # Grab button 1 to focus upon click
-        for amask in self.qtile.core._auto_modmasks():
-            self.qtile.core.conn.conn.core.GrabButton(
-                True,
-                self.window.wid,
-                EventMask.ButtonPress,
-                xcffib.xproto.GrabMode.Sync,
-                xcffib.xproto.GrabMode.Async,
-                xcffib.xproto.Atom._None,
-                xcffib.xproto.Atom._None,
-                1,
-                amask,
-            )
+        self._grab_click()
 
     @property
     def group(self):


Test patch:
diff --git a/test/test_window.py b/test/test_window.py
--- a/test/test_window.py
+++ b/test/test_window.py
@@ -92,6 +92,7 @@ def test_bring_front_click(manager, bring_front_click):
 
     # Click on window two
     manager.backend.fake_click(55, 55)
+    assert manager.c.window.info()["name"] == "two"
     wins = manager.backend.get_all_windows()
     if bring_front_click:
         assert wins.index(wids[0]) < wins.index(wids[2]) < wins.index(wids[1])
@@ -100,6 +101,7 @@ def test_bring_front_click(manager, bring_front_click):
 
     # Click on window one
     manager.backend.fake_click(10, 10)
+    assert manager.c.window.info()["name"] == "one"
     wins = manager.backend.get_all_windows()
     if bring_front_click == "floating_only":
         assert wins.index(wids[0]) < wins.index(wids[2]) < wins.index(wids[1])