internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: qtile/qtile

Issue:
client_focus and focus_change hooks seem to mean the same thing

# Issue description

There are two hooks with similar names: `client_focus` and `focus_change`. I can't tell what their distinction is conceptually.

We should either clarify the distinction (if there is one) or merge them.

# Qtile version

Master 55cc226


Discussion:
It looks like client_focus takes a window object as an argument so a config could include
```
@hook.subscribe.client_focus
def my_func(window):
    print(window.window.get_name())
```
while focus_change doesn't take any specific argument and searching through the [code](https://github.com/qtile/qtile/search?q=focus_change) it mostly seems like it's used internally to trigger widget updates
Nice, the distinction is subtle but don't think we need to merge them. `client_focus` happens when, as per the name, a client is focussed, and hooked functions receive the window. `focus_change` is more broad and also fires when focus is changed in the absence of windows, for example by changing which group is on screen. I'll post a fix to clarify this in case anyone else gets confused, like me :)

Resolving patch:
diff --git a/libqtile/hook.py b/libqtile/hook.py
--- a/libqtile/hook.py
+++ b/libqtile/hook.py
@@ -144,7 +144,8 @@ def changegroup(self, func):
         return self._subscribe("changegroup", func)
 
     def focus_change(self, func):
-        """Called when focus is changed
+        """Called when focus is changed, including moving focus between groups or when
+        focus is lost completely
 
         **Arguments**
 
@@ -217,7 +218,7 @@ def client_killed(self, func):
         return self._subscribe("client_killed", func)
 
     def client_focus(self, func):
-        """Called whenever focus changes
+        """Called whenever focus moves to a client window
 
         **Arguments**
 


Test patch:
Repository: qtile/qtile

Issue:
utils.has_transparency has print statement left in from testing
# Issue description
utils.has_transparency is printing bar colors to stdout.
https://github.com/qtile/qtile/blob/a3dcd5db984f3ab08ef3f89eff86e014dd367ee1/libqtile/utils.py#L127
I would submit a pr myself but my fork is currently a little snafu.

# Qtile version
0.18



# Configuration
in my config I have
```
bar.BAR(
    #other stuff
    background=["#000000","#000000","#000000","#003300"],)
```
This is showing up in stdout as: `['#000000', '#000000', '#000000', '#003300']`



Discussion:
That's my fault. I'll fix. 

Not sure why I used a print statement rather than logging...
No worries. print("got this far") gang unite! :)

Resolving patch:
diff --git a/libqtile/utils.py b/libqtile/utils.py
--- a/libqtile/utils.py
+++ b/libqtile/utils.py
@@ -124,7 +124,6 @@ def has_alpha(col):
         return has_alpha(colour)
 
     elif isinstance(colour, list):
-        print([c for c in colour])
         return any([has_transparency(c) for c in colour])
 
     return False


Test patch:
Repository: qtile/qtile

Issue:
bring_front_click is bool type but can be string
# bring_front_click is bool type but can be “floating_only”

qtile check reported error
error: config.bring_front_click variable differs from runtime type Literal['floating_only']

as per documentation floating_only is supported but `bring_front_click` variable is declared as bool type.
is it ok if I leave it as 'floating_only'?

# Qtile version : 1.8.1


Discussion:

Resolving patch:
diff --git a/libqtile/confreader.py b/libqtile/confreader.py
--- a/libqtile/confreader.py
+++ b/libqtile/confreader.py
@@ -31,7 +31,7 @@
 from libqtile.backend.x11 import core
 
 if TYPE_CHECKING:
-    from typing import Any, Dict, List
+    from typing import Any, Dict, List, Union
 
     from typing_extensions import Literal
 
@@ -44,7 +44,7 @@ class ConfigError(Exception):
 
 
 config_pyi_header = """
-from typing import Any, Dict, List
+from typing import Any, Dict, List, Union
 from typing_extensions import Literal
 from libqtile.config import Group, Key, Mouse, Rule, Screen
 from libqtile.layout.base import Layout
@@ -68,7 +68,7 @@ class Config:
     auto_fullscreen: bool
     widget_defaults: Dict[str, Any]
     extension_defaults: Dict[str, Any]
-    bring_front_click: bool
+    bring_front_click: Union[bool, Literal["floating_only"]]
     reconfigure_screens: bool
     wmname: str
     auto_minimize: bool


Test patch:
Repository: qtile/qtile

Issue:
BitcoinTicker migration does not work
```
/tmp/crypto cat config.py 
from libqtile.widget import BitcoinTicker

test = BitcoinTicker()
/tmp/crypto qtile migrate -c config.py 
Config unchanged.
/tmp/crypto cat config.py 
from libqtile.widget import BitcoinTicker

test = BitcoinTicker()
```

/cc @Graeme22


Discussion:

Resolving patch:
diff --git a/libqtile/scripts/migrate.py b/libqtile/scripts/migrate.py
--- a/libqtile/scripts/migrate.py
+++ b/libqtile/scripts/migrate.py
@@ -129,6 +129,7 @@ def new_at_current_to_new_client_position(query):
     tile_master_windows_rename,
     threaded_poll_text_rename,
     pacman_to_checkupdates,
+    bitcoin_to_crypto,
     hook_main_function,
     new_at_current_to_new_client_position,
 ]


Test patch:
diff --git a/test/test_migrate.py b/test/test_migrate.py
--- a/test/test_migrate.py
+++ b/test/test_migrate.py
@@ -169,6 +169,24 @@ def test_pacman():
     check_migrate(orig, expected)
 
 
+def test_crypto():
+    orig = textwrap.dedent("""
+        from libqtile import bar
+        from libqtile.widget import BitcoinTicker
+
+        bar.Bar([BitcoinTicker()], 30)
+    """)
+
+    expected = textwrap.dedent("""
+        from libqtile import bar
+        from libqtile.widget import CryptoTicker
+
+        bar.Bar([CryptoTicker()], 30)
+    """)
+
+    check_migrate(orig, expected)
+
+
 def test_main():
     orig = textwrap.dedent("""
         def main(qtile):
Repository: qtile/qtile

Issue:
stack trace from Clipboard widget
```
2021-08-13 06:48:23,421 ERROR libqtile hook.py:fire():L381 Error in hook selection_change
Traceback (most recent call last):
  File "/home/tycho/.local/lib/python3.9/site-packages/libqtile/hook.py", line 379, in fire
    i(*args, **kwargs)
  File "/home/tycho/.local/lib/python3.9/site-packages/libqtile/widget/clipboard.py", line 82, in hook_change
    if self.is_blacklisted(selection["owner"]):
  File "/home/tycho/.local/lib/python3.9/site-packages/libqtile/widget/clipboard.py", line 69, in is_blacklisted
    owner = xcbq.Window(self.qtile.core.conn, owner_id)
AttributeError: module 'libqtile.backend.x11.xcbq' has no attribute 'Window'
```


Discussion:

Resolving patch:
diff --git a/libqtile/widget/clipboard.py b/libqtile/widget/clipboard.py
--- a/libqtile/widget/clipboard.py
+++ b/libqtile/widget/clipboard.py
@@ -66,7 +66,7 @@ def is_blacklisted(self, owner_id):
         if owner_id in self.qtile.windows_map:
             owner = self.qtile.windows_map[owner_id].window
         else:
-            owner = xcbq.Window(self.qtile.core.conn, owner_id)
+            owner = xcbq.window.XWindow(self.qtile.core.conn, owner_id)
 
         owner_class = owner.get_wm_class()
         if owner_class:


Test patch:
Repository: qtile/qtile

Issue:
Wayland: mouseclicks not received by Internal windows when `bring_front_click` set to `"floating_only"`
# Issue description

Mouse clicks are not received by Internal windows. e.g. clicking on widgets in the bar does not trigger mouse callback events.

# Qtile version

Latest master: 76b3962d

# Stack traces

No errors shown in log on debug mode. However, there were no events at all when the mouse entered the bar.

# Configuration

This is caused when `bring_front_click` is set to `"floating_only"`


Discussion:
OK - it is my config. `default_config.py` seems to work. Will try to isolate the offending code but this could just be me being stupid.
Have identified the offending line. See updated details in first post.

Resolving patch:
diff --git a/libqtile/backend/wayland/core.py b/libqtile/backend/wayland/core.py
--- a/libqtile/backend/wayland/core.py
+++ b/libqtile/backend/wayland/core.py
@@ -671,11 +671,10 @@ def _focus_by_click(self) -> None:
         if found:
             win, surface, _, _ = found
 
-            if self.qtile.config.bring_front_click:
-                if (
-                    self.qtile.config.bring_front_click != "floating_only"
-                    or win.floating
-                ):
+            if self.qtile.config.bring_front_click is True:
+                win.cmd_bring_to_front()
+            elif self.qtile.config.bring_front_click == "floating_only":
+                if not isinstance(win, base.Internal) and win.floating:
                     win.cmd_bring_to_front()
 
             if not isinstance(win, base.Internal):


Test patch:
Repository: qtile/qtile

Issue:
Docs are failing to build (again)
See: https://readthedocs.org/projects/qtile/builds/15011707/

Looks like this is a dependency issue related to pywlroots.



Discussion:

Resolving patch:
diff --git a/docs/conf.py b/docs/conf.py
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -43,7 +43,25 @@ def __dir__(self):
     'keyring',
     'mpd',
     'psutil',
-    'trollius',
+    'pywayland',
+    'pywayland.protocol.wayland',
+    'pywayland.server',
+    'wlroots',
+    'wlroots.helper',
+    'wlroots.util',
+    'wlroots.util.box',
+    'wlroots.util.clock',
+    'wlroots.util.edges',
+    'wlroots.util.region',
+    'wlroots.wlr_types',
+    'wlroots.wlr_types.cursor',
+    'wlroots.wlr_types.keyboard',
+    'wlroots.wlr_types.layer_shell_v1',
+    'wlroots.wlr_types.output_management_v1',
+    'wlroots.wlr_types.pointer_constraints_v1',
+    'wlroots.wlr_types.server_decoration',
+    'wlroots.wlr_types.virtual_keyboard_v1',
+    'wlroots.wlr_types.xdg_shell',
     'xcffib',
     'xcffib.randr',
     'xcffib.render',
@@ -52,6 +70,7 @@ def __dir__(self):
     'xcffib.xinerama',
     'xcffib.xproto',
     'xdg.IconTheme',
+    'xkbcommon'
 ]
 sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES)
 


Test patch:
Repository: qtile/qtile

Issue:
Lazy spawncmd alias support
Hello, i had recently started using Qtile and i've stubled upon an issue that is really bothering me a lot.

Is there any chance i could make lazy.spawncmd run commands in my zshell so it would support all my precious aliases i spent hours to set up?


Discussion:
Your .zshrc is only read by zsh's interactive shell, not in command lines or scripts, so they won't have access to your aliases. What you can do instead is add files to your path that replicate aliases, i.e. make a small script (even if it's just one line) to execute a more complex command line, and give a it short name that is more convenient to type into a dialog like the prompt widget.
is it possible to make aliases directly in the spawncmd call? Like, pass it as an argument or something


Resolving patch:
diff --git a/libqtile/core/manager.py b/libqtile/core/manager.py
--- a/libqtile/core/manager.py
+++ b/libqtile/core/manager.py
@@ -1357,6 +1357,7 @@ def cmd_spawncmd(
         command: str = "%s",
         complete: str = "cmd",
         shell: bool = True,
+        aliases: Optional[Dict[str, str]] = None,
     ) -> None:
         """Spawn a command using a prompt widget, with tab-completion.
 
@@ -1370,9 +1371,16 @@ def cmd_spawncmd(
             command template (default: "%s").
         complete :
             Tab completion function (default: "cmd")
+        shell :
+            Execute the command with /bin/sh (default: True)
+        aliases :
+            Dictionary mapping aliases to commands. If the entered command is a key in
+            this dict, the command it maps to will be executed instead.
         """
         def f(args):
             if args:
+                if aliases and args in aliases:
+                    args = aliases[args]
                 self.cmd_spawn(command % args, shell=shell)
         try:
             mb = self.widgets_map[widget]


Test patch:
diff --git a/test/test_bar.py b/test/test_bar.py
--- a/test/test_bar.py
+++ b/test/test_bar.py
@@ -24,6 +24,7 @@
 
 import os
 import tempfile
+from pathlib import Path
 
 import pytest
 
@@ -32,6 +33,8 @@
 import libqtile.confreader
 import libqtile.layout
 import libqtile.widget
+from libqtile.command.base import CommandError
+from test.helpers import Retry
 
 
 class GBConfig(libqtile.confreader.Config):
@@ -133,7 +136,7 @@ def test_draw(manager):
 
 
 @gb_config
-def test_prompt(manager):
+def test_prompt(manager, monkeypatch):
     assert manager.c.widget["prompt"].info()["width"] == 0
     manager.c.spawncmd(":")
     manager.c.widget["prompt"].fake_keypress("a")
@@ -143,6 +146,17 @@ def test_prompt(manager):
     manager.c.widget["prompt"].fake_keypress("slash")
     manager.c.widget["prompt"].fake_keypress("Tab")
 
+    script = Path(__file__).parent / "scripts" / "window.py"
+    manager.c.spawncmd(":", aliases={"w": script.as_posix()})
+    manager.c.widget["prompt"].fake_keypress("w")
+    manager.c.widget["prompt"].fake_keypress("Return")
+
+    @Retry(ignore_exceptions=(CommandError,))
+    def is_spawned():
+        return manager.c.window.info()
+
+    is_spawned()
+
 
 @gb_config
 def test_event(manager):
Repository: qtile/qtile

Issue:
_NET_FRAME_EXTENTS not implemented
According to window manager [specification](https://specifications.freedesktop.org/wm-spec/latest/ar01s05.html#idm45623293938880) `_NET_FRAME_EXTENTS` MUST be implemented, but it is not in Qtile 0.18.1. This might cause issues for some applications.


Discussion:

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
@@ -432,6 +432,8 @@ def paint_borders(self, depth, colors, borderwidth, width, height):
         """
         This method is used only by the managing Window class.
         """
+        self.set_property('_NET_FRAME_EXTENTS', [borderwidth] * 4)
+
         if not colors or not borderwidth:
             return
 
diff --git a/libqtile/backend/x11/xcbq.py b/libqtile/backend/x11/xcbq.py
--- a/libqtile/backend/x11/xcbq.py
+++ b/libqtile/backend/x11/xcbq.py
@@ -171,6 +171,7 @@ def rdict(d):
     "_NET_WM_STRUT_PARTIAL": ("CARDINAL", 32),
     "_NET_WM_WINDOW_OPACITY": ("CARDINAL", 32),
     "_NET_WM_WINDOW_TYPE": ("ATOM", 32),
+    "_NET_FRAME_EXTENTS": ("CARDINAL", 32),
     # Net State
     "_NET_WM_STATE": ("ATOM", 32),
     # Xembed


Test patch:
diff --git a/test/backend/x11/test_window.py b/test/backend/x11/test_window.py
--- a/test/backend/x11/test_window.py
+++ b/test/backend/x11/test_window.py
@@ -728,3 +728,36 @@ def test_multiple_borders(xmanager):
         next_avg = sum(color) / 3
         assert avg < next_avg
         avg = next_avg
+
+
+class NetFrameExtentsConfig(BareConfig):
+    layouts = [
+        layout.Columns(border_width=2, border_on_single=True),
+        layout.Columns(border_width=4, border_on_single=True),
+    ]
+    floating_layout = layout.Floating(border_width=6)
+
+
+@pytest.mark.parametrize("xmanager", [NetFrameExtentsConfig], indirect=True)
+def test_net_frame_extents(xmanager):
+    conn = xcbq.Connection(xmanager.display)
+
+    def assert_frame(wid, frame):
+        r = conn.conn.core.GetProperty(
+            False,
+            wid,
+            conn.atoms["_NET_FRAME_EXTENTS"],
+            conn.atoms["CARDINAL"],
+            0,
+            (2 ** 32) - 1
+        ).reply()
+        assert r.value.to_atoms() == frame
+
+    pid = xmanager.test_window("one")
+    wid = xmanager.c.window.info()["id"]
+    assert_frame(wid, (2, 2, 2, 2))
+    xmanager.c.next_layout()
+    assert_frame(wid, (4, 4, 4, 4))
+    xmanager.c.window.enable_floating()
+    assert_frame(wid, (6, 6, 6, 6))
+    xmanager.kill_window(pid)
Repository: qtile/qtile

Issue:
Reload configuration on SIGHUP
I have a shell script that is executed on a uevent from udev. In this script, I have to restart Qtile. At the moment I'm accomplishing this with the following:

`echo restart | qshell -s /home/matt/.cache/qtile/qtilesocket.\:0.0 &> /dev/null`

This isn't ideal due to the hard coded qtilesocket path. Would it be ok to add the ability to either restart Qtile or reload the configuration file when Qtile receives a SIGHUP, adhering to the Unix convention?


Discussion:
That should be fine to add that functionality and pretty easy with the asyncio signal handlers [1]. In the interim, if you are using the default socket location, you don't need to call qshell with the socket name, also the `-c` flag can be used to pass in a command.

[1] https://docs.python.org/3/library/asyncio-eventloop.html#unix-signals
Implemented in #2114
Reverted in #2257 because of #2256.
I think it would be fine to use SIGUSR1 for this.

Resolving patch:
diff --git a/libqtile/core/manager.py b/libqtile/core/manager.py
--- a/libqtile/core/manager.py
+++ b/libqtile/core/manager.py
@@ -209,6 +209,8 @@ async def async_loop(self) -> None:
                 signal.SIGTERM: self.stop,
                 signal.SIGINT: self.stop,
                 signal.SIGHUP: self.stop,
+                signal.SIGUSR1: self.cmd_reload_config,
+                signal.SIGUSR2: self.cmd_restart,
             }), ipc.Server(
                 self._prepare_socket_path(self.socket_path),
                 self.server.call,
@@ -248,6 +250,8 @@ def dump_state(self, buf) -> None:
     def cmd_reload_config(self) -> None:
         """
         Reload the configuration file.
+
+        Can also be triggered by sending Qtile a SIGUSR1 signal.
         """
         logger.debug('Reloading the configuration file')
 
@@ -1060,7 +1064,11 @@ def cmd_validate_config(self) -> None:
             send_notification("Configuration check", "No error found!")
 
     def cmd_restart(self) -> None:
-        """Restart qtile"""
+        """
+        Restart Qtile.
+
+        Can also be triggered by sending Qtile a SIGUSR2 signal.
+        """
         if not self.core.supports_restarting:
             raise CommandError(f"Backend does not support restarting: {self.core.name}")
 


Test patch:
Repository: qtile/qtile

Issue:
Pomodoro widget duplicates the prefix and suffix texts of the fmt key
```
widget.Pomodoro(
    fmt='prefix{}suffix',
),

widget.TextBox(
    fmt='prefix{}suffix',
    text='TEXTBOX'
),
```

### 1. Pomodoro widget


_expected to display:_


> **prefix**POMODORO**suffix**

_actual:_

> **prefixprefix**POMODORO**suffixsuffix**


### 2. TextBox widget (for example)

_expected to dispay = actual:_

>**prefix**TEXTBOX**suffix**


## Description:

- If there is prefix or suffix in **fmt** key at Pomodoro widget, It doubles the text of prefix or suffix

`qtile -v: 0.18.1`
`logs: nothing relevant`
- [x]  I have searched past issues to see if this bug has already been reported. *




Discussion:
I'm a bit confused by this. Are you saying it actually prints the word "prefix" twice?

Pomodoro has a number of different prefixes which are set via configuration options rather than the `fmt` variable so I can see why you could end up with `prefix{pomodoro prefix}pomodoro{suffix}`.

Can you post a screenshot?
I am new to Qtile and actually don't use `fmt` because I search the internet and **I wasn't fount proper use example** except for Pango markup _(but also I can use Pango markup in `format` key and I think Pango not specific to `fmt` key)_.

I was trying the pomodoro widget and **_experimenting_** `fmt` to see If I can print like {P:  0:24:59} (P for shorthand Pomodoro) or **{0:24:59 <--}** (for permanent suffix like <--)
Yes I am aware there is prefix keys for `pomodoro` and I shouldn't use `prefix` word to give example, my bad.

![0](https://user-images.githubusercontent.com/50280168/144921484-56aa4e80-6655-4f4a-8b88-c0e26e464258.png)
![1](https://user-images.githubusercontent.com/50280168/144921523-8e4f8edd-4976-46bb-a525-ced8f90822aa.png)

```
widget.Pomodoro(
    fmt='before{}after',
),
```

Thanks. I can recreate this. It's very odd.

Will look to get it fixed!

Resolving patch:
diff --git a/libqtile/widget/pomodoro.py b/libqtile/widget/pomodoro.py
--- a/libqtile/widget/pomodoro.py
+++ b/libqtile/widget/pomodoro.py
@@ -29,7 +29,6 @@ class Pomodoro(base.ThreadPoolText):
     """Pomodoro technique widget"""
     orientations = base.ORIENTATION_HORIZONTAL
     defaults = [
-        ("fmt", "{}", "fmt"),
         ("num_pomodori", 4, "Number of pomodori to do in a cycle"),
         ("length_pomodori", 25, "Length of one pomodori in minutes"),
         ("length_short_break", 5, "Length of a short break in minutes"),
@@ -171,4 +170,4 @@ def _send_notification(self, urgent, message):
         send_notification("Pomodoro", message, urgent=urgent)
 
     def poll(self):
-        return self.fmt.format(self._get_text())
+        return self._get_text()


Test patch:
Repository: qtile/qtile

Issue:
TreeTab panel on the right side
I really like the TreeTab layout for my development environments. But I need that panel to be on the right side, because it is causing a bend for my head. I am not used to reading with an offset. 


Discussion:

Resolving patch:
diff --git a/libqtile/layout/tree.py b/libqtile/layout/tree.py
--- a/libqtile/layout/tree.py
+++ b/libqtile/layout/tree.py
@@ -387,6 +387,7 @@ class TreeTab(Layout):
         ("panel_width", 150, "Width of the left panel"),
         ("sections", ['Default'], "Foreground color of inactive tab"),
         ("previous_on_rm", False, "Focus previous window on close instead of first."),
+        ("place_right", False, "Place the tab panel on the right side"),
     ]
 
     def __init__(self, **config):
@@ -552,7 +553,10 @@ def show_section_tree(root):
     def show(self, screen_rect):
         if not self._panel:
             self._create_panel(screen_rect)
-        panel, body = screen_rect.hsplit(self.panel_width)
+        if self.place_right:
+            body, panel = screen_rect.hsplit(screen_rect.width - self.panel_width)
+        else:
+            panel, body = screen_rect.hsplit(self.panel_width)
         self._resize_panel(panel)
         self._panel.unhide()
 
@@ -735,7 +739,10 @@ def _create_drawer(self, screen_rect):
         )
 
     def layout(self, windows, screen_rect):
-        panel, body = screen_rect.hsplit(self.panel_width)
+        if self.place_right:
+            body, panel = screen_rect.hsplit(screen_rect.width - self.panel_width)
+        else:
+            panel, body = screen_rect.hsplit(self.panel_width)
         self._resize_panel(panel)
         Layout.layout(self, windows, body)
 


Test patch: