# -*- python -*-
'''
xpybar – xmobar replacement written in python
Copyright © 2014, 2015, 2016, 2017, 2018, 2019 Mattias Andrée (m@maandreese)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
# A xpybar configuration example when application launchers
import os
import sys
import time
from plugins.image import Image
from plugins.application import Application
OUTPUT, HEIGHT, YPOS, TOP = 0, 24, 24, True
Image.theme_preferences = ['hicolor', 'mate', 'gnome', 'Adwaita', ..., 'ContrastHigh']
class Launcher:
def __init__(self, icon, *command):
self.icon = Image(icon, height = HEIGHT, icon = '/' not in icon)
self.command = list(command)
def launch(self):
if os.fork() == 0:
if os.fork() == 0:
os.setpgrp()
os.execvp(self.command[0], self.command)
sys.exit(0)
def scroll_up(self):
pass
def scroll_down(self):
pass
class LauncherSet:
def __init__(self, launchers):
self.launchers = [Launcher(x[0], *x[1:]) for x in launchers]
self.current = 0
self.icon = self.launchers[self.current].icon
def launch(self):
self.launchers[self.current].launch()
def scroll_up(self):
self.current = (self.current - 1) % len(self.launchers)
self.icon = self.launchers[self.current].icon
bar.invalidate()
def scroll_down(self):
self.current = (self.current + 1) % len(self.launchers)
self.icon = self.launchers[self.current].icon
bar.invalidate()
def desktop(file):
application = Application(file)
icon = application.get_setting('Icon')
command = Application.strip_placeholders(application.get_setting('Exec'))
return (icon, 'sh', '-c', command)
launchers = [ [ ('accessories-calculator', 'mate-calc')
, ('accessories-character-map', 'mucharmap')
, ('scanner', 'simple-scan')
, ('meld', 'meld')
]
, [ ('dia', 'dia')
, desktop ('inkscape')
, desktop ('gimp')
, ('calligrakrita', 'krita')
, ('blender', 'blender')
, ('/usr/share/pixmaps/openscad.png', 'openscad')
]
, [ ('emacs', 'emacs')
, ('audacity', 'audacity')
, ('/usr/share/ardour4/icons/ardour_icon_48px.png', 'ardour4')
]
, [ ('vlc', 'vlc')
, ('deluge', 'deluge')
, ('/usr/share/pixmaps/amule.xpm', 'amule')
]
, ('claws-mail', 'claws-mail')
, [ ('terminator', 'terminator')
, ('cool-retro-term', 'cool-retro-term')
, ('/usr/share/pixmaps/xterm-color_48x48.xpm', 'xterm')
]
]
launchers = [Launcher(x[0], *x[1:]) if isinstance(x, tuple) else LauncherSet(x) for x in launchers]
start_ = start
def start():
start_()
def reaper():
while True:
try:
os.wait()
except:
time.sleep(3)
xasync(reaper, name = 'reaper')
def redraw():
bar.clear()
offset = 0
for launcher in launchers:
launcher.icon.draw(bar, offset, 0)
offset += HEIGHT
LEFT_BUTTON = 1
RIGHT_BUTTON = 3
SCROLL_UP = 4
SCROLL_DOWN = 5
def unhandled_event(e):
'''
Invoked when an unrecognised even is polled,
feel free to replace this completely
@param e The event
'''
if isinstance(e, Xlib.protocol.event.ButtonPress):
x = e.event_x // HEIGHT
button = e.detail
if 0 <= x < len(launchers):
if button == LEFT_BUTTON: launchers[x].launch()
elif button == RIGHT_BUTTON: launchers[x].scroll_down()
elif button == SCROLL_UP: launchers[x].scroll_up()
elif button == SCROLL_DOWN: launchers[x].scroll_down()
# TODO support for dropping files onto the launchers to open with those files would be nice