kuro-qtile-theme/kuro/utils/general.py

246 lines
6.4 KiB
Python

import re
import subprocess
from time import sleep
import notify2
import six
from libqtile import widget
from libqtile.window import Internal
from libqtile.bar import Bar
from notify2 import Notification, URGENCY_NORMAL
notify2.init("QTileWM")
BUTTON_LEFT = 1
BUTTON_MIDDLE = 2
BUTTON_RIGHT = 3
BUTTON_SCROLL_UP = 4
BUTTON_SCROLL_DOWN = 5
def is_running(process):
s = subprocess.Popen(["ps", "axuw"], stdout=subprocess.PIPE)
if isinstance(process, list):
process = "".join(process)
for x in s.stdout:
if re.search(process, x.decode('utf-8')):
return True
return False
def execute(process):
if isinstance(process, list):
return subprocess.Popen(process)
elif isinstance(process, str):
return subprocess.Popen(process.split())
else:
pass
def execute_once(process):
if not is_running(process):
if isinstance(process, list):
return subprocess.Popen(process)
elif isinstance(process, str):
return subprocess.Popen(process.split())
else:
pass
def call_process(command, **kwargs):
"""
This method uses `subprocess.check_output` to run the given command
and return the string from stdout, which is decoded when using
Python 3.
"""
output = subprocess.check_output(command, **kwargs)
if six.PY3:
output = output.decode()
return output
def get_screen_count():
try:
output = subprocess.check_output("xrandr -q".split()).decode('utf-8')
output = [x for x in output.split("\n") if " connected" in x]
except subprocess.CalledProcessError:
return 1
if output:
return len(output)
else:
return 1
def bar_separator(config):
return widget.Sep(foreground=config.get('colour_spacer_background', '#777777'),
linewidth=config.get('width_spacer', 1),
padding=config.get('padding_spacer', 4),
)
def notify(title, content, urgency=URGENCY_NORMAL, timeout=5000, image=None):
if image is not None:
notification = Notification(
summary=title, message=content,
icon=image
)
else:
notification = Notification(
summary=title, message=content
)
notification.set_timeout(timeout)
notification.set_urgency(urgency)
return notification.show()
def spawn_popup(qtile, x, y, text):
"""
:param qtile: The main qtile instance
:type qtile: Qtile
:param x: x-coordinate
:type x: int
:param y: y-coordinate
:type y: int
:param text: String to display
:type text: str
:return: The popup instance
:rtype: Internal
"""
popup = Internal.create(
qtile, x, y, 100, 100, opacity=1
)
# Create textwidget for in window
popup.bordercolor = "#000000"
popup.borderwidth = 1
popup.focus(False)
#popup.
return popup
def despawn_popup(popup):
"""
:type popup: Internal
:param popup: The popup to despawn
"""
popup.kill()
def test_popups(qtile):
popup = spawn_popup(qtile, 10, 10, "Hello World!")
sleep(3)
despawn_popup(popup)
def display_wm_class(qtile):
window = qtile.currentWindow if qtile else None
if window:
wm_class = window.window.get_wm_class() or None
name = window.name
if wm_class:
notify(title="WM_Class of {}".format(name),
content="{}".format(wm_class),
urgency=notify2.URGENCY_CRITICAL)
def bluetooth_audio_sink():
try:
output = subprocess.check_output("pamixer --list-sinks".split()).decode("utf-8")
output = [x for x in output.split('\n') if "blue" in x.lower()]
except (subprocess.CalledProcessError, FileNotFoundError):
return -1
sink = -1
try:
sink = int(output[0].split()[0])
except IndexError:
pass
except AttributeError:
pass
except ValueError:
pass
return sink
def bluetooth_audio_connected():
return bluetooth_audio_sink() != -1
class KuroTopBar(Bar):
def __init__(self, theme, widgets, size, **config):
self.theme = theme
super(KuroTopBar, self).__init__(widgets, size, **config)
def _configure(self, qtile, screen):
super(KuroTopBar, self)._configure(qtile, screen)
self.window.handle_EnterNotify = self.handle_enter_notify
self.window.handle_LeaveNotify = self.handle_leave_notify
self.window.window.set_property("_NET_WM_NAME", "KuroTopBar")
self.window.update_name()
def draw(self):
if self.queued_draws == 0:
self.qtile.call_soon(self._actual_draw)
self.queued_draws += 1
def _actual_draw(self):
self.queued_draws = 0
self._resize(self.length, self.widgets)
for i in self.widgets:
i.draw()
if self.widgets:
end = i.offset + i.length
if end < self.length:
if self.horizontal:
self.drawer.draw(offsetx=end, width=self.length - end)
else:
self.drawer.draw(offsety=end, height=self.length - end)
self.theme.update_visualizers()
def handle_enter_notify(self, e):
# self.theme.log_debug("Bar HandleEnterNotify")
#
# self.window.opacity = Config.get('bar_hover_opacity', 1.0)
# print("Bar Hover Enter")
#
# try:
# hovered_widget = [x for x in self.widgets if (x.offsetx + x.width) >= e.event_x][0]
# except IndexError:
# hovered_widget = None
#
# self.theme.log_debug("Hovered over {}".format(hovered_widget))
#
# if hasattr(hovered_widget, "handle_hover_enter"):
# hovered_widget.handle_hover_enter(e)
self.draw()
def handle_leave_notify(self, e):
# self.theme.log_debug("Bar HandleLeaveNotify")
#
# self.window.opacity = Config.get('bar_opacity', 1.0)
# print("Bar Hover Leave")
#
# try:
# hovered_widget = [x for x in self.widgets if (x.offsetx + x.width) >= e.event_x][0]
# except IndexError:
# hovered_widget = None
#
# self.theme.log_debug("Hovered over {}".format(hovered_widget))
#
# if hasattr(hovered_widget, "handle_hover_leave"):
# hovered_widget.handle_hover_leave(e)
self.draw()