Init commit
This commit is contained in:
commit
93531f44dd
6 changed files with 417 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
__pycache__
|
224
config.py
Normal file
224
config.py
Normal file
|
@ -0,0 +1,224 @@
|
|||
from libqtile.config import Key, Screen, Group, Drag, Click
|
||||
from libqtile.lazy import lazy
|
||||
from libqtile import layout, bar, widget, hook
|
||||
|
||||
from typing import List # noqa: F401
|
||||
from os import getenv, environ, execl
|
||||
from subprocess import run, Popen
|
||||
|
||||
import widget_custom
|
||||
|
||||
mod = "mod4"
|
||||
newpath = getenv("PATH").replace("/opt/qtile/venv/bin", "")
|
||||
exitvenv = f"env -u VIRTUAL_ENV PATH='{newpath}'"
|
||||
|
||||
|
||||
def cmd_run(prompt, sudo=False):
|
||||
name = "cmd"
|
||||
if sudo:
|
||||
name += "(root)"
|
||||
def f(args):
|
||||
if sudo:
|
||||
args = f"sudo -A {args}"
|
||||
Popen(f"{exitvenv} {args}", shell=True)
|
||||
|
||||
prompt.start_input(name, f, "cmd")
|
||||
|
||||
|
||||
def hard_restart(misc):
|
||||
execl("/opt/qtile/qtile-venv-entry", " ")
|
||||
|
||||
|
||||
keys = [
|
||||
# Switch between windows in current stack pane
|
||||
Key([mod], "k", lazy.layout.down()),
|
||||
Key([mod], "j", lazy.layout.up()),
|
||||
|
||||
# Move windows up or down in current stack
|
||||
Key([mod, "control"], "k", lazy.layout.shuffle_down()),
|
||||
Key([mod, "control"], "j", lazy.layout.shuffle_up()),
|
||||
|
||||
# Switch window focus to other pane(s) of stack
|
||||
Key([mod], "Tab", lazy.layout.next()),
|
||||
|
||||
# Swap panes of split stack
|
||||
Key([mod, "shift"], "space", lazy.layout.rotate()),
|
||||
|
||||
# Toggle between split and unsplit sides of stack.
|
||||
# Split = all windows displayed
|
||||
# Unsplit = 1 window displayed, like Max layout, but still with
|
||||
# multiple stack panes
|
||||
Key([mod, "shift"], "Return", lazy.layout.toggle_split()),
|
||||
|
||||
# Toggle between different layouts as defined below
|
||||
Key([mod], "space", lazy.next_layout()),
|
||||
Key([mod], "w", lazy.window.kill()),
|
||||
|
||||
# Windows opacity
|
||||
Key([mod, "shift"], "o", lazy.window.down_opacity()),
|
||||
Key([mod, "shift"], "t", lazy.window.up_opacity()),
|
||||
|
||||
# Qtile managment
|
||||
Key([mod, "control"], "r", lazy.restart()),
|
||||
Key([mod, "control"], "f", lazy.function(hard_restart)),
|
||||
Key([mod, "control"], "q", lazy.shutdown()),
|
||||
Key([mod, "control"], "s", lazy.spawn("systemctl poweroff")),
|
||||
Key([mod, "control"], "v", lazy.spawn("xtrlock"), lazy.spawn("systemctl suspend")),
|
||||
|
||||
# Run
|
||||
Key([mod], "r", lazy.widget["prompt"].function(cmd_run)),
|
||||
Key([mod, "shift"], "r", lazy.widget["prompt"].function(cmd_run, True)),
|
||||
|
||||
# Lock
|
||||
Key([mod], "l", lazy.spawn(f"xtrlock")),
|
||||
Key([mod, "control"], "l", lazy.spawn(f"parrots -n 9 -l")),
|
||||
Key([mod, "shift"], "l", lazy.spawn(f"xtrlock -b")),
|
||||
|
||||
# Brightness
|
||||
Key(["mod1"], "F7", lazy.spawn("xbrightness 0.5")),
|
||||
Key(["mod1"], "F6", lazy.spawn("xbrightness +0.2")),
|
||||
Key(["mod1"], "F5", lazy.spawn("xbrightness -0.2")),
|
||||
|
||||
# Audio
|
||||
Key([], "XF86AudioRaiseVolume", lazy.spawn("amixer -c 0 -D default -q set Master 2%+")),
|
||||
Key([], "XF86AudioLowerVolume", lazy.spawn("amixer -c 0 -D default -q set Master 2%-")),
|
||||
Key([], "XF86AudioMute", lazy.spawn("amixer -c 0 -D default -q set Master toggle")),
|
||||
|
||||
# Apps
|
||||
Key([mod, "mod1"], "k", lazy.spawn(f"{exitvenv} kitty")),
|
||||
Key([mod, "mod1"], "v", lazy.spawn(f"{exitvenv} vivaldi")),
|
||||
Key([mod, "mod1"], "d", lazy.spawn(f"{exitvenv} discord")),
|
||||
Key([mod, "mod1"], "t", lazy.spawn(f"{exitvenv} telegram-desktop")),
|
||||
|
||||
|
||||
# Notify
|
||||
Key([mod, "mod1"], "Right", lazy.widget["notify"].next()),
|
||||
Key([mod, "mod1"], "Left", lazy.widget["notify"].prev()),
|
||||
Key([mod, "mod1"], "Down", lazy.widget["notify"].clear()),
|
||||
|
||||
]
|
||||
|
||||
|
||||
groups = []
|
||||
for i in [["F1", "\N{globe with meridians}"], ["F2", "\N{incoming envelope}"], ["F3", "\N{briefcase}"], ["F4", "\N{floppy disk}"], ["F5", "\N{bookmark tabs}"], ["F6", "\N{video game}"]]:
|
||||
groups.append(Group(i[1]))
|
||||
keys.extend([
|
||||
Key([mod], i[0], lazy.group[i[1]].toscreen()),
|
||||
Key([mod, "shift"], i[0], lazy.window.togroup(i[1], switch_group=True))
|
||||
])
|
||||
|
||||
|
||||
layouts = [
|
||||
layout.Max(),
|
||||
layout.Stack(num_stacks=2),
|
||||
# Try more layouts by unleashing below layouts.
|
||||
# layout.Bsp(),
|
||||
#layout.Columns(),
|
||||
#layout.Matrix(),
|
||||
#layout.MonadTall(),
|
||||
#layout.MonadWide(),
|
||||
#layout.RatioTile(),
|
||||
#layout.Tile()
|
||||
#layout.TreeTab(),
|
||||
#layout.VerticalTile(),
|
||||
#layout.Zoomy(),
|
||||
]
|
||||
|
||||
|
||||
widget_defaults = dict(
|
||||
font='sans',
|
||||
fontsize=12,
|
||||
padding=3,
|
||||
)
|
||||
extension_defaults = widget_defaults.copy()
|
||||
|
||||
|
||||
screens = [
|
||||
Screen(
|
||||
top=bar.Bar(
|
||||
[
|
||||
widget.CurrentLayoutIcon(),
|
||||
widget.GroupBox(hide_unused=True),
|
||||
widget.Prompt(),
|
||||
widget.TaskList(txt_floating="🗗", txt_maximized="🗖", txt_minimized="🗕"),
|
||||
widget.Systray(),
|
||||
widget.Notify(),
|
||||
widget.CheckUpdates(custom_command="apt list --upgradable", execute="sudo -A apt update", display_format="{updates}", colour_have_updates="ff7300", colour_no_updates="5eff00"),
|
||||
widget.Sep(),
|
||||
widget.CPU(format="{load_percent}%"),
|
||||
widget_custom.Memory(),
|
||||
widget.ThermalSensor(tag_sensor="Core 0"),
|
||||
widget.Sep(),
|
||||
widget.Wlan(disconnected_message="", interface="wlp1s0"),
|
||||
widget.Net(format="{down}\u2193\u2191{up}"),
|
||||
widget.Sep(),
|
||||
#widget.BatteryIcon(battery="BATC"),
|
||||
widget.Battery(charge_char="\N{electric plug}", discharge_char="\N{battery}", empty_char="\N{cross mark}", unknown_char="\N{question mark}", battery="BATC", format="{char}{percent:2.0%} {hour:d}:{min:02d}", low_percentage=0.35, hide_threshold=True),
|
||||
widget.Volume(front="material-design-icons-iconfont",emoji=True),
|
||||
widget.Clock(format='%d/%m/%Y %H:%M'),
|
||||
],
|
||||
24,
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
# 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())
|
||||
]
|
||||
|
||||
|
||||
dgroups_key_binder = None
|
||||
dgroups_app_rules = [] # type: List
|
||||
follow_mouse_focus = True
|
||||
bring_front_click = True
|
||||
cursor_warp = False
|
||||
floating_layout = layout.Floating(float_rules=[
|
||||
{'wmclass': 'confirm'},
|
||||
{'wmclass': 'dialog'},
|
||||
{'wmclass': 'download'},
|
||||
{'wmclass': 'error'},
|
||||
{'wmclass': 'file_progress'},
|
||||
{'wmclass': 'notification'},
|
||||
{'wmclass': 'splash'},
|
||||
{'wmclass': 'toolbar'},
|
||||
{'wmclass': 'confirmreset'}, # gitk
|
||||
{'wmclass': 'makebranch'}, # gitk
|
||||
{'wmclass': 'maketag'}, # gitk
|
||||
{'wname': 'branchdialog'}, # gitk
|
||||
{'wname': 'pinentry'}, # GPG key password entry
|
||||
{'wname': 'Onboard'},
|
||||
{'wmclass': 'ssh-askpass'}, # ssh-askpass
|
||||
])
|
||||
|
||||
auto_fullscreen = True
|
||||
focus_on_window_activation = "smart"
|
||||
|
||||
|
||||
@hook.subscribe.client_new
|
||||
def func(c):
|
||||
if c.name == "Vivaldi - Vivaldi":
|
||||
c.togroup("\N{globe with meridians}")
|
||||
elif c.name in ["Discord", "Telegram"]:
|
||||
c.togroup("\N{incoming envelope}")
|
||||
elif c.name == "Typora":
|
||||
c.togroup("\N{briefcase}")
|
||||
elif c.name == "win0":
|
||||
c.togroup("\N{floppy disk}")
|
||||
elif c.name == "docs":
|
||||
c.togroup("\N{bookmark tabs}")
|
||||
elif c.name in ["Lutris", "Shadow"]:
|
||||
c.togroup("\N{video game}")
|
||||
|
||||
|
||||
def main(q):
|
||||
Popen(["nextcloud", "--background"])
|
||||
Popen("kdeconnect-indicator")
|
||||
|
||||
wmname = "LG3D"
|
||||
|
30
qtile-venv-entry
Executable file
30
qtile-venv-entry
Executable file
|
@ -0,0 +1,30 @@
|
|||
#!/bin/bash
|
||||
|
||||
export SUDO_ASKPASS=/usr/bin/ssh-askpass
|
||||
export _JAVA_AWT_WM_NONREPARENTING=1
|
||||
|
||||
picom --vsync --backend glx -b
|
||||
pulseaudio -D
|
||||
|
||||
feh --bg-fill ~/Nextcloud/Images/Furry/Commis/Kat-LUK.J_/poster_etha.png
|
||||
xbrightness 0.5
|
||||
|
||||
# Fix touchscreen
|
||||
xinput set-prop "pointer:ELAN22A6:00 04F3:22A6" --type=float "Coordinate Transformation Matrix" 0 1 0 -1 0 1 0 0 1
|
||||
# setup touchpad parameters
|
||||
touchpadid=`xinput list | grep Touchpad | cut -d= -f2 | cut -f1`
|
||||
tapid=`xinput list-props $touchpadid | grep "Tapping Enabled" | grep -v "Default" | cut -d'(' -f2 | cut -d')' -f1`
|
||||
middleid=`xinput list-props $touchpadid | grep "Middle Emulation Enabled" | grep -v "Default" | cut -d'(' -f2 | cut -d')' -f1`
|
||||
scrollid=`xinput list-props $touchpadid | grep "Natural Scrolling Enabled" | grep -v "Default" | cut -d'(' -f2 | cut -d')' -f1`
|
||||
speedid=`xinput list-props $touchpadid | grep "Coordinate Transformation Matrix" | grep -v "Default" | cut -d'(' -f2 | cut -d')' -f1`
|
||||
disablewhiletypingid=`xinput list-props $touchpadid | grep "Disable While Typing Enabled" | grep -v "Default" | cut -d'(' -f2 | cut -d')' -f1`
|
||||
xinput set-prop $touchpadid $tapid 1
|
||||
xinput set-prop $touchpadid $middleid 1
|
||||
xinput set-prop $touchpadid $scrollid 0
|
||||
xinput set-prop $touchpadid $speedid 5 0 0 0 5 0 0 0 2
|
||||
xinput set-prop $touchpadid $disablewhiletypingid 0
|
||||
|
||||
|
||||
source /opt/qtile/venv/bin/activate
|
||||
python /opt/qtile/bin/qtile $* > /opt/qtile/qtile.log
|
||||
|
1
widget_custom/__init__.py
Normal file
1
widget_custom/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
from widget_custom.memory import Memory
|
43
widget_custom/memory.py
Normal file
43
widget_custom/memory.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
import psutil
|
||||
|
||||
from libqtile.widget import base
|
||||
|
||||
__all__ = ["Memory"]
|
||||
|
||||
|
||||
class Memory(base.ThreadedPollText):
|
||||
"""Displays memory/swap usage
|
||||
|
||||
MemUsed: Returns memory in use
|
||||
MemTotal: Returns total amount of memory
|
||||
MemFree: Returns amount of memory free
|
||||
Buffers: Returns buffer amount
|
||||
Active: Returns active memory
|
||||
Inactive: Returns inactive memory
|
||||
Shmem: Returns shared memory
|
||||
SwapTotal: Returns total amount of swap
|
||||
SwapFree: Returns amount of swap free
|
||||
SwapUsed: Returns amount of swap in use
|
||||
"""
|
||||
|
||||
orientations = base.ORIENTATION_HORIZONTAL
|
||||
defaults = [
|
||||
("format", "{MemUsed}%", "Formatting for field names."),
|
||||
("update_interval", 1.0, "Update interval for the Memory"),
|
||||
]
|
||||
|
||||
def __init__(self, **config):
|
||||
super().__init__(**config)
|
||||
self.add_defaults(Memory.defaults)
|
||||
|
||||
def tick(self):
|
||||
self.update(self.poll())
|
||||
return self.update_interval
|
||||
|
||||
def poll(self):
|
||||
mem = psutil.virtual_memory()
|
||||
swap = psutil.swap_memory()
|
||||
val = {}
|
||||
val["MemUsed"] = round((mem.used / mem.total) * 100)
|
||||
return self.format.format(**val)
|
||||
|
118
widget_custom/notify.py
Normal file
118
widget_custom/notify.py
Normal file
|
@ -0,0 +1,118 @@
|
|||
from . import base
|
||||
from .. import bar, utils, pangocffi
|
||||
from libqtile.notify import notifier
|
||||
from os import path
|
||||
|
||||
|
||||
class Notify(base._TextBox):
|
||||
"""A notify widget"""
|
||||
orientations = base.ORIENTATION_HORIZONTAL
|
||||
defaults = [
|
||||
("foreground_urgent", "ff0000", "Foreground urgent priority colour"),
|
||||
("foreground_low", "dddddd", "Foreground low priority colour"),
|
||||
(
|
||||
"default_timeout",
|
||||
None,
|
||||
"Default timeout (seconds) for notifications"
|
||||
),
|
||||
("audiofile", None, "Audiofile played during notifications"),
|
||||
]
|
||||
|
||||
def __init__(self, width=bar.CALCULATED, **config):
|
||||
base._TextBox.__init__(self, "", width, **config)
|
||||
self.add_defaults(Notify.defaults)
|
||||
notifier.register(self.update)
|
||||
self.current_id = 0
|
||||
|
||||
def _configure(self, qtile, bar):
|
||||
base._TextBox._configure(self, qtile, bar)
|
||||
self.layout = self.drawer.textlayout(
|
||||
self.text,
|
||||
self.foreground,
|
||||
self.font,
|
||||
self.fontsize,
|
||||
self.fontshadow,
|
||||
markup=True
|
||||
)
|
||||
|
||||
def set_notif_text(self, notif):
|
||||
self.text = pangocffi.markup_escape_text(notif.summary)
|
||||
urgency = notif.hints.get('urgency', 1)
|
||||
if urgency != 1:
|
||||
self.text = '<span color="%s">%s</span>' % (
|
||||
utils.hex(
|
||||
self.foreground_urgent if urgency == 2
|
||||
else self.foreground_low
|
||||
),
|
||||
self.text
|
||||
)
|
||||
if notif.body:
|
||||
self.text = '<span weight="bold">%s</span> - %s' % (
|
||||
self.text, pangocffi.markup_escape_text(notif.body)
|
||||
)
|
||||
if self.audiofile and path.exists(self.audiofile):
|
||||
self.qtile.cmd_spawn("aplay -q '%s'" % self.audiofile)
|
||||
|
||||
def update(self, notif):
|
||||
self.qtile.call_soon_threadsafe(self.real_update, notif)
|
||||
|
||||
def real_update(self, notif):
|
||||
self.set_notif_text(notif)
|
||||
self.current_id = notif.id - 1
|
||||
if notif.timeout and notif.timeout > 0:
|
||||
self.timeout_add(notif.timeout / 1000, self.clear)
|
||||
elif self.default_timeout:
|
||||
self.timeout_add(self.default_timeout, self.clear)
|
||||
self.bar.draw()
|
||||
return True
|
||||
|
||||
def display(self):
|
||||
self.set_notif_text(notifier.notifications[self.current_id])
|
||||
self.bar.draw()
|
||||
|
||||
def clear(self):
|
||||
self.text = ''
|
||||
self.current_id = len(notifier.notifications) - 1
|
||||
self.bar.draw()
|
||||
|
||||
def prev(self):
|
||||
if self.current_id > 0:
|
||||
self.current_id -= 1
|
||||
self.display()
|
||||
|
||||
def next(self):
|
||||
if self.current_id < len(notifier.notifications) - 1:
|
||||
self.current_id += 1
|
||||
self.display()
|
||||
|
||||
def button_press(self, x, y, button):
|
||||
if button == 1:
|
||||
self.clear()
|
||||
elif button == 4:
|
||||
self.prev()
|
||||
elif button == 5:
|
||||
self.next()
|
||||
|
||||
def cmd_display(self):
|
||||
"""Display the notifcication"""
|
||||
self.display()
|
||||
|
||||
def cmd_clear(self):
|
||||
"""Clear the notification"""
|
||||
self.clear()
|
||||
|
||||
def cmd_toggle(self):
|
||||
"""Toggle showing/clearing the notification"""
|
||||
if self.text == '':
|
||||
self.display()
|
||||
else:
|
||||
self.clear()
|
||||
|
||||
def cmd_prev(self):
|
||||
"""Show previous notification"""
|
||||
self.prev()
|
||||
|
||||
def cmd_next(self):
|
||||
"""Show next notification"""
|
||||
self.next()
|
||||
|
Reference in a new issue