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()

Reply via email to