Repository: qtile/qtile

Issue:
Some tui programs (ranger) don't receive SIGWINCH correctly
Since the upgrade to v0.18 I have [this](https://github.com/ranger/ranger/issues/2473) problem with ranger, where other terminal file managers like lf an joshuto have no issue. I've been told that's a problem with ranger getting SIGWINCH from qtile when resizing the window. Is there a solution for this?
Terminal apps open with wrong dimensions when launched with key bindings
<!--
Please do not ask general questions here! There are [community
contact](https://github.com/qtile/qtile#community) options for that.
-->

# Issue description

<!--
A brief discussion of what failed and how it failed. A description of
what you tried is helpful, i.e. "When I use lazy.kill() on a window I get
the following stack trace" instead of "Closing windows doesn't work".
-->
When launching terminal apps through keybindings, the dimensions of the output window aren't determined correctly. I'll use Ranger as an example but it's the same for all my terminal apps (Newsboat, Neomutt etc.)

Current behaviour:

![1611979751](https://user-images.githubusercontent.com/59050442/106346832-6100dc80-62d3-11eb-898b-42a19c3e20ea.png)

Expected behaviour:

![1611979773](https://user-images.githubusercontent.com/59050442/106346811-344cc500-62d3-11eb-97fc-2f83df63725f.png)

I can only observe the expected behaviour when I launch the terminal app manually (without the use of keybindings).

# Qtile version

<!--
Please include the exact commit hash of the version of Qtile that failed.
-->
```
> qtile --version

 0.16.2.dev209+gd5848931
```

This problem doesn't seem to exist in the stable version of qtile (0.16.1) that was released in the August of last year. I didn't make any changes to my config file when I switched from qtile to qtile-git, so I assume something must have changed between the two versions to cause this.

# Stack traces

<!--
Please attach any stack traces found in:

* `~/.xsession-errors`
* `~/.local/share/qtile/qtile.log`
-->

This is today's log:
```
> .local/share/qtile/qtile.log

2021-01-30 08:08:52,292 WARNING libqtile floating.py:__init__():L108 Non-config.Match objects in float_rules are deprecated
2021-01-30 10:26:14,969 WARNING libqtile.widget.pulse_volume pulse_volume.py:on_connection_change():L97 Connection to pulseaudio has been terminated
2021-01-30 10:26:14,976 WARNING libqtile lifecycle.py:_atexit():L38 Qtile will now terminate
2021-01-30 10:28:07,362 ERROR libqtile hook.py:fire():L367 Error in hook client_new
Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/libqtile/hook.py", line 365, in fire
    i(*args, **kwargs)
  File "/home/masacaai/.config/qtile/config.py", line 72, in transparent_window
    change_transparency(window)
  File "/home/masacaai/.config/qtile/config.py", line 50, in change_transparency
    kls = window.window.get_wm_class()[1].lower()
IndexError: tuple index out of range
2021-01-30 11:48:37,758 ERROR libqtile.widget.pulse_volume pulse_volume.py:on_connection_change():L104 Connection to pulseaudio has been terminated
2021-01-30 11:48:42,934 WARNING libqtile floating.py:__init__():L108 Non-config.Match objects in float_rules are deprecated
2021-01-30 17:15:00,569 ERROR libqtile hook.py:fire():L403 Error in hook client_new
Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/libqtile/hook.py", line 401, in fire
    i(*args, **kwargs)
  File "/home/masacaai/.config/qtile/config.py", line 72, in transparent_window
    change_transparency(window)
  File "/home/masacaai/.config/qtile/config.py", line 50, in change_transparency
    kls = window.window.get_wm_class()[1].lower()
IndexError: tuple index out of range
2021-01-30 17:59:44,319 WARNING libqtile floating.py:__init__():L108 Non-config.Match objects in float_rules are deprecated
2021-01-30 17:59:44,324 WARNING libqtile.widget.pulse_volume pulse_volume.py:on_connection_change():L97 Connection to pulseaudio has been terminated
2021-01-30 17:59:44,331 ERROR libqtile base.py:_wrapper():L300 got exception from widget timer
Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/libqtile/widget/base.py", line 298, in _wrapper
    method(*method_args)
  File "/usr/lib/python3.9/site-packages/libqtile/widget/base.py", line 463, in timer_setup
    update_interval = self.tick()
  File "/usr/lib/python3.9/site-packages/libqtile/widget/base.py", line 490, in tick
    self.update(text)
  File "/usr/lib/python3.9/site-packages/libqtile/widget/base.py", line 493, in update
    old_width = self.layout.width
  File "/usr/lib/python3.9/site-packages/libqtile/drawer.py", line 80, in width
    return self.layout.get_pixel_size()[0]
  File "/usr/lib/python3.9/site-packages/libqtile/pangocffi.py", line 132, in get_pixel_size
    pango.pango_layout_get_pixel_size(self._pointer, width, height)
TypeError: initializer for ctype 'PangoLayout *' must be a cdata pointer, not NoneType
2021-01-30 17:59:44,336 ERROR libqtile base.py:_wrapper():L300 got exception from widget timer
Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/libqtile/widget/base.py", line 298, in _wrapper
    method(*method_args)
  File "/usr/lib/python3.9/site-packages/libqtile/widget/base.py", line 463, in timer_setup
    update_interval = self.tick()
  File "/usr/lib/python3.9/site-packages/libqtile/widget/base.py", line 490, in tick
    self.update(text)
  File "/usr/lib/python3.9/site-packages/libqtile/widget/base.py", line 493, in update
    old_width = self.layout.width
  File "/usr/lib/python3.9/site-packages/libqtile/drawer.py", line 80, in width
    return self.layout.get_pixel_size()[0]
  File "/usr/lib/python3.9/site-packages/libqtile/pangocffi.py", line 132, in get_pixel_size
    pango.pango_layout_get_pixel_size(self._pointer, width, height)
TypeError: initializer for ctype 'PangoLayout *' must be a cdata pointer, not NoneType
2021-01-30 17:59:44,338 ERROR libqtile base.py:on_done():L542 Failed to reschedule.
Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/libqtile/widget/base.py", line 534, in on_done
    self.update(result)
  File "/usr/lib/python3.9/site-packages/libqtile/widget/base.py", line 550, in update
    old_width = self.layout.width
  File "/usr/lib/python3.9/site-packages/libqtile/drawer.py", line 80, in width
    return self.layout.get_pixel_size()[0]
  File "/usr/lib/python3.9/site-packages/libqtile/pangocffi.py", line 132, in get_pixel_size
    pango.pango_layout_get_pixel_size(self._pointer, width, height)
TypeError: initializer for ctype 'PangoLayout *' must be a cdata pointer, not NoneType
2021-01-30 17:59:44,340 WARNING libqtile lifecycle.py:_atexit():L34 Restarting Qtile with os.execv(...)
2021-01-30 17:59:44,947 WARNING libqtile floating.py:__init__():L108 Non-config.Match objects in float_rules are deprecated

```

The two biggest errors I can spot with my untrained eye is one regarding a function I had written to make sure mpv stays with the same opacity even when it loses focus and another TypeError regarding PangoLayout.

The transparency function works as intended and I wouldn't have noticed anything had I not checked the log.

# Configuration

<!--
Please include a link or attach your configuration to the issue.
-->
I believe these are the relevant parts of my config. Let me know if I need to post more:

```
##############
# FUNCTIONS  #
##############

def change_transparency(window):
    """change window transparency based on his name/type."""    
    
    kls = window.window.get_wm_class()[1].lower()
    if window.window.get_wm_icon_name() == 'Picture-in-Picture' or 'mpv' in kls:
    	window.cmd_opacity(1)
    else:
    	window.cmd_opacity(opacity_var)

#########
# HOOKS #
#########

@hook.subscribe.client_new
def transparent_window(window):
    """Make new windows a little transparent."""
    change_transparency(window)
            
@hook.subscribe.client_focus
def client_focus(window):
    """Change transparency on focus."""
    global last_focus

    if last_focus is not None and last_focus != window:
        try:
            change_transparency(last_focus)
        except Exception:
            pass  # ignore if error

    if last_focus != window:
        last_focus = window
        window.cmd_opacity(1)  # current focused window: no transp

###############
# KEYBINDINGS #
###############

Key([mod], "r",
lazy.spawn("kitty -e ranger"),
desc="Launch ranger"),

```

Everything regarding the transparency of unfocused windows wasn't written by me. I had taken it from someone else's config. If that indeed seems to be the root of the problem, I'll link the original post/issue somewhere here.

# Links

I had initially opened this as a discussion, which can be found here #2164 
This issue may be linked with this mailing list discussion : https://groups.google.com/g/qtile-dev/c/mjMKB533GNA/m/f0UGhBxpDgAJ


Discussion:
I assume you're running an X11 backend here.

I don't know much about SIGWINCH but I would have thought that X11 should be responsible for issuing that signal when a window changes size.

Let me do some digging...
Confirmed that this was working in v0.16.0 but it breaks in v0.17.

Doing a git bisect reveals that the first bad commit is: 6a5f3bd7 which makes no sense!

More investigating.
Sounds like https://github.com/qtile/qtile/issues/2167
Yeah, I was thinking exactly the same.

I'm going to redo my bisect because I wonder if I went wrong somewhere. I just can't see why that commit would cause the issue.
Same commit.
> Sounds like #2167

The difference is that it doesn't work properly even if I launch it from the terminal
> Confirmed that this was working in v0.16.0 but it breaks in v0.17.
> 
> Doing a git bisect reveals that the first bad commit is: [6a5f3bd](https://github.com/qtile/qtile/commit/6a5f3bd781353b0922545f06927a41880adb1bae) which makes no sense!
> 
> More investigating.

What the ... that is the same commit as https://github.com/qtile/qtile/issues/2167#issuecomment-779734552. I'm puzzled. If I have some time I will look into this.
i was doing some testing and seems that this behaviour happen with this commit 6a5f3bd781353b0922545f06927a41880adb1bae

this commit 908b910d00087ece13bb576f672c94bcf9e6fc43 seems to be fine, after killing qtile

edit:
seems that resizing window with ranger inside kitty/alacritty/xterm is broken too…
in 0.16.0 ranger was updating it's size with window, now stay the same size, and LINES/COLUMNS workaround don't seem to work for that
This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 30 days.
Ping. Is there a definite cause or solution for this? This problem still occurs but I have no clue why the lines/columns env vars are set at all in my case...
Noticed strange thing about this issue as I was testing it with kitty+ranger.

Inside i3wm, this issue doesn't exists. But if I run the same i3wm inside Xephyr inside qtile it is present. And if I run the same i3wm inside Xephyr inside xfce4, it is not.
This problem has been bugging me for a while, and I finally noticed three things about it when I ran into while trying to fix the problem I found and reported in #2546. I am not an expert in this area, but this information may be useful for someone who is.

1. The size of drawn area when it is too small is the same as the correct size for the default window size (i.e. the size that it is created if you open the window in floating mode). As such, starting them in floating mode results in perfectly normal UI.
2. Nvim (and probably some other programs) seem to fix it if you resize them. (Either by switching them in and out of floating mode or otherwise changing the tile size.) Ranger does not seem to do this.
3. At least Nvim seems to have this behavior inconsistently. I used to think that it was any time I launched it directly, but there is a chance for it to spawn with the interface the right size. This makes me suspect that it may be time dependent in some way. I am not very knowledgeable of the source code for these apps or Qtile, but possible explanation is the terminal window being initiated at it's default size and then being resized to the space it is supposed to fill by Qtile. This might work fine with most apps, but terminal apps that don't always have a perfect integration with the actual GUI they are being displayed in (because they don't dynamically resize (ranger) or have some other problem as Nvim does) may have issues.
I have a hacky fix for these issues which can be found on amongst my dotfiles here https://github.com/justinesmithies/dotfiles
Basically if you add the lines as featured below in a script it'll work and I just alias to my scripts for the correct names like ranger.
My ranger-fix script

```
#!/bin/bash
COLUMNS=
LINES=
(kitty --class ranger -e ranger $@ & ) > /dev/null 2>&1
```


In my .bashrc

`alias ranger='ranger-fix'`

Hope this helps you and others. 

> I have a hacky fix for these issues which can be found on amongst my dotfiles here https://github.com/justinesmithies/dotfiles
> Basically if you add the lines as featured below in a script it'll work and I just alias to my scripts for the correct names like ranger.
> My ranger-fix script
> 
> ```
> #!/bin/bash
> COLUMNS=
> LINES=
> (kitty --class ranger -e ranger $@ & ) > /dev/null 2>&1
> ```
> 
> In my .bashrc
> 
> `alias ranger='ranger-fix'`
> 
> Hope this helps you and others.

Hi, thank you for that. 
But though that fixes the sizing problem, I've got another problem. When I open a file trough ranger, opened that way, I got nano as my editor, even though I've set nvim as my editor in my fish config. When I open files through ranger in the usual way (from the terminal) it opens with nvim. Any thoughts on why that happens?
You do have the following in your .bashrc don't you ?

export EDITOR="nvim"

On Wed, 8 Sep 2021, 23:26 rpm89, ***@***.***> wrote:

> I have a hacky fix for these issues which can be found on amongst my
> dotfiles here https://github.com/justinesmithies/dotfiles
> Basically if you add the lines as featured below in a script it'll work
> and I just alias to my scripts for the correct names like ranger.
> My ranger-fix script
>
> #!/bin/bash
> COLUMNS=
> LINES=
> (kitty --class ranger -e ranger $@ & ) > /dev/null 2>&1
>
> In my .bashrc
>
> alias ranger='ranger-fix'
>
> Hope this helps you and others.
>
> Hi, thank you for that.
> But though that fixes the sizing problem, I've got another problem. When I
> open a file trough ranger, opened that way, I got nano as my editor, even
> though I've set nvim as my editor in my fish config. When I open files
> through ranger in the usual way (from the terminal) it opens with nvim. Any
> thoughts on why that happens?
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <https://github.com/qtile/qtile/issues/2167#issuecomment-915615439>, or
> unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAL7VKSK2ZY2QNZGJMGLFVLUA7PKHANCNFSM4W2LQVLA>
> .
> Triage notifications on the go with GitHub Mobile for iOS
> <https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
> or Android
> <https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
>
>

Actually scrub that last comment as you're using fish. Thinking about it
you should check your rangers .config/ranger for the file rifle.conf as
this states what apps open what files.
https://github.com/ranger/ranger/blob/master/ranger/config/rifle.conf

On Wed, 8 Sep 2021, 23:29 Justine Smithies, ***@***.***> wrote:

> You do have the following in your .bashrc don't you ?
>
> export EDITOR="nvim"
>
> On Wed, 8 Sep 2021, 23:26 rpm89, ***@***.***> wrote:
>
>> I have a hacky fix for these issues which can be found on amongst my
>> dotfiles here https://github.com/justinesmithies/dotfiles
>> Basically if you add the lines as featured below in a script it'll work
>> and I just alias to my scripts for the correct names like ranger.
>> My ranger-fix script
>>
>> #!/bin/bash
>> COLUMNS=
>> LINES=
>> (kitty --class ranger -e ranger $@ & ) > /dev/null 2>&1
>>
>> In my .bashrc
>>
>> alias ranger='ranger-fix'
>>
>> Hope this helps you and others.
>>
>> Hi, thank you for that.
>> But though that fixes the sizing problem, I've got another problem. When
>> I open a file trough ranger, opened that way, I got nano as my editor, even
>> though I've set nvim as my editor in my fish config. When I open files
>> through ranger in the usual way (from the terminal) it opens with nvim. Any
>> thoughts on why that happens?
>>
>> —
>> You are receiving this because you commented.
>> Reply to this email directly, view it on GitHub
>> <https://github.com/qtile/qtile/issues/2167#issuecomment-915615439>, or
>> unsubscribe
>> <https://github.com/notifications/unsubscribe-auth/AAL7VKSK2ZY2QNZGJMGLFVLUA7PKHANCNFSM4W2LQVLA>
>> .
>> Triage notifications on the go with GitHub Mobile for iOS
>> <https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
>> or Android
>> <https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
>>
>>
>

> Actually scrub that last comment as you're using fish. Thinking about it you should check your rangers .config/ranger for the file rifle.conf as this states what apps open what files. https://github.com/ranger/ranger/blob/master/ranger/config/rifle.conf
> […](#)
> On Wed, 8 Sep 2021, 23:29 Justine Smithies, ***@***.***> wrote: You do have the following in your .bashrc don't you ? export EDITOR="nvim" On Wed, 8 Sep 2021, 23:26 rpm89, ***@***.***> wrote: > I have a hacky fix for these issues which can be found on amongst my > dotfiles here https://github.com/justinesmithies/dotfiles > Basically if you add the lines as featured below in a script it'll work > and I just alias to my scripts for the correct names like ranger. > My ranger-fix script > > #!/bin/bash > COLUMNS= > LINES= > (kitty --class ranger -e ranger $@ & ) > /dev/null 2>&1 > > In my .bashrc > > alias ranger='ranger-fix' > > Hope this helps you and others. > > Hi, thank you for that. > But though that fixes the sizing problem, I've got another problem. When > I open a file trough ranger, opened that way, I got nano as my editor, even > though I've set nvim as my editor in my fish config. When I open files > through ranger in the usual way (from the terminal) it opens with nvim. Any > thoughts on why that happens? > > — > You are receiving this because you commented. > Reply to this email directly, view it on GitHub > <[#2167 (comment)](https://github.com/qtile/qtile/issues/2167#issuecomment-915615439)>, or > unsubscribe > <https://github.com/notifications/unsubscribe-auth/AAL7VKSK2ZY2QNZGJMGLFVLUA7PKHANCNFSM4W2LQVLA> > . > Triage notifications on the go with GitHub Mobile for iOS > <https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675> > or Android > <https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>. > >

That helped, thank you!
Hacky fix through python function
UPDATE: Implement Tokariew' solution in the way that works for me:
```python
def fix_cli_app(app: 'Name of $PATH located application') -> str:
    '''Quick fix of github.com/qtile/qtile/issues/2167 bug'''
    fix_environment = 'export -n LINES; export -n COLUMNS; sleep 0.1 &&'
    return f'alacritty -t {app} -e sh -c "{fix_environment} {app}"'


keys = [
    Key([mod], 'r', lazy.spawn(fix_cli_app('ranger'))),
    Key([mod], 'n', lazy.spawn(fix_cli_app('newsboat'))),
]
```
for fish I added following Lines to config.fish
```
set --unexport COLUMNS
set --unexport LINES
```
fixes issue for me completly

edit:
for bash using this lines in .bashrc fix this issue for me
```
export -n LINES
export -n COLUMNS
```
For Bash this is what I do:

https://github.com/justinesmithies/qtile-dotfiles/blob/master/.bashrc

On Tue, 5 Oct 2021, 03:09 Tokariew, ***@***.***> wrote:

> for fish I added following Lines to config.fish
>
> set --unexport COLUMNS
> set --unexport LINES
>
> fixes issue for me completly
> not sure if there is fixing it for bash/zsh
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <https://github.com/qtile/qtile/issues/2167#issuecomment-933999452>, or
> unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAL7VKQAFGNMP3LBMZPMK6LUFJM5DANCNFSM4W2LQVLA>
> .
> Triage notifications on the go with GitHub Mobile for iOS
> <https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
> or Android
> <https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
>
>

Also checkout the Qtile wiki here:

https://github.com/qtile/qtile/wiki/Fixes-for-apps-having-issues-in-Qtile

On Tue, 5 Oct 2021, 03:09 Tokariew, ***@***.***> wrote:

> for fish I added following Lines to config.fish
>
> set --unexport COLUMNS
> set --unexport LINES
>
> fixes issue for me completly
> not sure if there is fixing it for bash/zsh
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <https://github.com/qtile/qtile/issues/2167#issuecomment-933999452>, or
> unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAL7VKQAFGNMP3LBMZPMK6LUFJM5DANCNFSM4W2LQVLA>
> .
> Triage notifications on the go with GitHub Mobile for iOS
> <https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
> or Android
> <https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
>
>

Might be related, check this out: 

https://user-images.githubusercontent.com/61395246/136042705-1b538a1d-7f35-4b1a-9b5f-b8c6011ea730.mp4

When called with a shortcut ,
If i try editing the config ( using the ` , + c ` key bind if it matters ) , and the exit `:x`, it quits the whole application...
again, called from the terminal has no issues...
> export -n LINES
> export -n COLUMNS

For ZSH I used `unset` , but it didn't fix it sadly.

Also , resizing the window fixes the UI problem.

Resolving patch:
diff --git a/libqtile/sh.py b/libqtile/sh.py
--- a/libqtile/sh.py
+++ b/libqtile/sh.py
@@ -25,10 +25,10 @@
 import inspect
 import pprint
 import re
-import readline
 import struct
 import sys
 import termios
+from importlib import import_module
 from typing import Any, List, Optional, Tuple
 
 from libqtile.command.client import CommandClient
@@ -54,12 +54,16 @@ class QSh:
     """Qtile shell instance"""
 
     def __init__(self, client: CommandInterface, completekey="tab") -> None:
+        # Readline is imported here to prevent issues with terminal resizing
+        # which would result from readline being imported when qtile is first
+        # started
+        self.readline = import_module("readline")
         self._command_client = CommandClient(client)
         self._completekey = completekey
         self._builtins = [i[3:] for i in dir(self) if i.startswith("do_")]
 
     def complete(self, arg, state) -> Optional[str]:
-        buf = readline.get_line_buffer()
+        buf = self.readline.get_line_buffer()
         completers = self._complete(buf, arg)
         if completers and state < len(completers):
             return completers[state]
@@ -331,9 +335,9 @@ def process_line(self, line: str) -> Any:
         return "Invalid command: {}".format(line)
 
     def loop(self) -> None:
-        readline.set_completer(self.complete)
-        readline.parse_and_bind(self._completekey + ": complete")
-        readline.set_completer_delims(" ()|")
+        self.readline.set_completer(self.complete)
+        self.readline.parse_and_bind(self._completekey + ": complete")
+        self.readline.set_completer_delims(" ()|")
 
         while True:
             try:


Test patch: