Dear Qtile friends,
I am writing to you, because I found several issues and weak points in our
favourite WM. Since I've switched to Qtile and use it for almost two months
as my primary WM in work, it is really awesome, that I've found so few of
them. I've listed them in this email, instead of bug tracker, because I am
not sure if they are really bugs or maybe my wrong configuration, so I
don't want to spam bug tracker. I want to ask you, if you could tell me,
which of them I should properly file.
## Issues
A1) On dual monitor setup with monitors A, B where A is a primary, dialog
windows are spawned always on actual group displayed on monitor A even if
focus is on B. Most easily reproducible by `gmrun` or `libreoffice`
launcher.
A2) On Max layout, when non-master window is focused and dialog appears,
after closing it, focus is changed to master window. This is realy, realy
bad and makes using some applications very painful (dolphin - create new;
file-roller - extracting)
A3) Fullscreen - sometimes I get the real fullscreen, sometimes I still see
my panels (i.e. in flash) and have to do `lazy.window.toggle_fullscreen()`.
Also sometimes when entering fullscreen in flash, esc key or cursor keys
doesn't work. You have to click to get focus and then it works. And also
when there is multiple windows in `Max` layout and one of them opens
fullscreen (flash), fullscreen window doesnt even get the focus, so its
under other windows.
A4) When unplugging external monitor, master window from external monitor
sometimes moves to actual group showed on primary monitor. It should stay
in the group where it was before.
## Would like to
B1) Keybinding to set text = "" on Notify widget
B2) Clicking (with some modifier or right mouse) on notify should redirect
to the highlighted window
B3) On dual monitor setup, when one screen attempts to show group which is
already showed on the other screen, attempt is successfull and other screen
is switched to something else. I would rather to just not be able to open
it, because in 99% cases I think that focus is on the other screen and then
it smashes my setup.
The most irritating sorted by level of caused desperation are B3 > A2 > A3.
I think that fixing all of them doesn't have to be so hard, I think that
you just maybe haven't encountered them.
Thank you very much.
Sincerely yours,
FrostyX
--
You received this message because you are subscribed to the Google Groups
"qtile-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
import re
import subprocess
from os import uname
from os.path import expanduser
from libqtile.config import Key, Screen, Group, Drag, Click, Match
from libqtile.command import lazy, Client
from libqtile import layout, bar, widget, hook
terminal = "gnome-terminal"
run = "gmrun"
hostname = uname()[1]
if hostname == "...":
pass
mod = "mod1" # Left alt
sup = "mod4" # Left win-key
keys = [
# Switch window focus to other pane(s) of stack
Key([mod], "Tab", lazy.layout.next()),
Key([mod], "Return", lazy.spawn(terminal)),
Key([mod], "F1", lazy.spawn(terminal)),
Key([mod], "F2", lazy.spawn(run)),
# Toggle between different layouts as defined below
Key([mod], "space", lazy.nextlayout()),
Key([mod], "F4", lazy.window.kill()),
Key([mod, "control"], "r", lazy.restart()),
Key([mod, "control"], "q", lazy.shutdown()),
Key([mod], "w", lazy.screen.togglegroup()),
# cycle to previous and next group
Key([mod], "h", lazy.screen.prevgroup()),
Key([mod], "l", lazy.screen.nextgroup()),
Key([sup], "f", lazy.window.toggle_fullscreen()),
# Process `gnome-screensaver` must run
Key([mod, sup], "l", lazy.spawn("gnome-screensaver-command -l")),
# Multihead magic
Key([sup], "h", lazy.to_screen(0)),
Key([sup], "l", lazy.to_screen(1)),
# Multimedia
Key([], "XF86AudioRaiseVolume", lazy.spawn("amixer -q -D pulse sset Master 2%+")),
Key([], "XF86AudioLowerVolume", lazy.spawn("amixer -q -D pulse sset Master 2%-")),
Key([], "XF86AudioMute", lazy.spawn("amixer -q -D pulse set Master toggle")),
Key([], "XF86MonBrightnessUp", lazy.spawn("xbacklight -inc 10")),
Key([], "XF86MonBrightnessDown", lazy.spawn("xbacklight -dec 10")),
]
workspaces = [
{"name": "i", "key": "i", "matches": [Match(wm_class=["Pidgin"])]},
{"name": "r", "key": "r", "matches": [Match(wm_class=["Chromium-browser", "Firefox", "Google-chrome"])]},
{"name": "f", "key": "f", "matches": [Match(wm_class=["Dolphin", "Thunar", "File-roller"])]},
{"name": "d", "key": "d", "matches": [Match(wm_class=["Lispworks", "jetbrains-pycharm", "Eclipse" ])]},
{"name": "q", "key": "q", "matches": [Match(wm_class=["Acroread", "Zathura"])]},
{"name": "n", "key": "n", "matches": [Match(wm_class=["Claws-mail"])]},
{"name": "c", "key": "c"},
{"name": "v", "key": "v", "matches": [Match(wm_class=["VirtualBox"])]},
{"name": "g", "key": "g", "matches": [Match(wm_class=["Wine", "Python2.7", "Steam", "Progress"])]}, # Python2.7 is playonlinux; Progress is steam updater
{"name": "o", "key": "o", "matches": [Match(wm_class=["Vlc"])]},
]
groups = []
for workspace in workspaces:
#icon = "/home/frostyx/.config/qtile/icons/invaders.png"
#icon = None
matches = workspace["matches"] if "matches" in workspace else None
#groups.append(Group(workspace["name"], icon=icon, matches=matches))
groups.append(Group(workspace["name"], matches=matches))
keys.append(Key([mod], workspace["key"], lazy.group[workspace["name"]].toscreen()))
keys.append(Key([mod, sup], workspace["key"], lazy.window.togroup(workspace["name"])))
# float dialog windows
@hook.subscribe.client_new
def dialogs(window):
floating = ["gmrun", "gcr-prompter"]
wm_type = window.window.get_wm_type()
wm_class = window.window.get_wm_class()[0]
transient_for = window.window.get_wm_transient_for()
if wm_type == 'dialog' or transient_for or wm_class in floating:
window.floating = True
# floating_layout = layout.Floating(auto_float_types=[
# "notification",
# "toolbar",
# "splash",
# "dialog",
# ])
colors = {
"grey": "#555555",
"red": "#DD1144",
"blue": "#445588",
"lgrey": "#b8b6b1",
"green": "#008080",
}
# http://docs.qtile.org/en/latest/manual/ref/layouts.html
layout_theme = {
"border_width": 1,
"border_focus": colors["blue"],
"border_normal": colors["lgrey"],
}
layouts = [
layout.MonadTall(**layout_theme),
layout.TreeTab(),
layout.xmonad.MonadTall(ratio=0.75, **layout_theme),
layout.max.Max(),
]
floating_layout = layout.Floating(**layout_theme)
widget_defaults = dict(
font='Arial',
fontsize=12,
padding=3,
)
class _WindowTabs(widget.WindowTabs):
separator = " | "
def update(self):
widget.WindowTabs.update(self)
# Very ugly hack
names = self.text.split(self.separator)
self.text = self.separator.join(names)
self.bar.draw()
def num_screens():
process = subprocess.Popen(["xrandr"], stdout=subprocess.PIPE)
out = process.communicate()[0].split("\n")
i = 0
for line in out:
if " connected " in line:
i += 1
return i
# class ScreenBox(widget.base._TextBox):
# def __init__(self, width=bar.CALCULATED, **config):
# widget.base._TextBox.__init__(self, "", width, **config)
#
# def _configure(self, qtile, bar):
# widget.base._TextBox._configure(self, qtile, bar)
# self.text = "0"
# self.setup_hooks()
#
# def screen(self):
# return Client().screen.info()["index"]
#
# def setup_hooks(self):
# def hook_response():
# pass
# #self.text = "{}".format(self.screen())
# #self.bar.draw()
# hook.subscribe.current_screen_change(hook_response)
screens = [
Screen(
top=bar.Bar([
# Temp
widget.TextBox(text="Temp:"),
widget.ThermalSensor(threshold=65, foreground_alert=colors["red"]),
widget.Sep(padding=15),
# Battery
widget.TextBox(text="Battery:"),
widget.Battery(battery_name="BAT1", low_foreground=colors["red"]),
#widget.BatteryIcon(),
widget.Sep(padding=15),
# Light
widget.TextBox(text="Light:"),
widget.Backlight(
brightness_file="/sys/class/backlight/intel_backlight/actual_brightness",
max_brightness_file="/sys/class/backlight/intel_backlight/max_brightness"
),
widget.Sep(padding=15),
# Volume
widget.TextBox(text="Volume:"),
widget.Volume(get_volume_command="amixer -D pulse get Master".split()),
widget.Sep(padding=15),
# Screen
# widget.TextBox(text="Screen:"),
# ScreenBox(),
# widget.Sep(padding=15),
widget.Notify(foreground_low=colors["red"][1:], foreground_urgent=colors["red"][1:]),
widget.Spacer(),
widget.Clock(timezone="Europe/Prague", format="%H:%M %d. %m. (%b) %Y"),
], 25),
bottom=bar.Bar([
widget.GroupBox(highlight_method="block", this_current_screen_border=colors["blue"]),
widget.Sep(padding=15),
widget.CurrentLayout(),
widget.Sep(padding=15),
widget.Prompt(),
#widget.WindowName(),
#widget.WindowTabs(),
_WindowTabs(),
widget.Systray(),
], 25),
)
]
if num_screens() == 2:
screens.append(
Screen(
bottom=bar.Bar([
widget.GroupBox(highlight_method="block", this_current_screen_border=colors["blue"]),
widget.Sep(padding=15),
widget.CurrentLayout(),
widget.Sep(padding=15),
widget.Prompt(),
_WindowTabs(),
widget.Systray(),
], 25)))
# Drag floating layouts.
mouse = [
Drag([mod], "Button1", lazy.window.set_position_floating(), start=lazy.window.get_position()),
Drag([mod], "Button3", lazy.window.set_size_floating(), start=lazy.window.get_size()),
Click([mod], "Button2", lazy.window.bring_to_front())
]
follow_mouse_focus = False
bring_front_click = False
dgroups_key_binder = None
dgroups_app_rules = []
main = None
cursor_warp = False
auto_fullscreen = True
wmname = "LG3D"
# Autostart
@hook.subscribe.startup_once
def autostart():
home = expanduser("~")
subprocess.Popen([home + "/.config/qtile/autostart.sh"])
# xrandr --output DP2 --auto --right-of eDP1
@hook.subscribe.screen_change
def restart_on_randr(qtile, ev):
qtile.cmd_restart()