This commit removes and replaces all the old methods 'on_*' by settings with the same name. The old methods were renamed into more explicit names that can be used for the callbacks like "next_song","mute" etc... For instance, you can test with: status.register("clock", format=[ ("Format 0",'Europe/London'), ("%a %-d Format 1",'Europe/Dublin'), "%a %-d %b %X format 2", ("%a %-d %b %X format 3", 'Europe/Paris'), ], on_leftclick= ["urxvtc"] , # launch urxvtc on left click on_rightclick= ["scroll_format", 2] , # update format by steps of 2 log_level=logging.DEBUG, ) This way much code could be removed from other modules, though I did it only for the clock module here.
This commit is contained in:
parent
98e46ac3d6
commit
d31cc380ef
@ -46,10 +46,10 @@ class ALSA(IntervalModule):
|
||||
alsamixer = None
|
||||
has_mute = True
|
||||
|
||||
on_scrollup = "increase_volume"
|
||||
on_scrolldown = "decrease_volume"
|
||||
on_lclick = "switch_mute"
|
||||
on_rclick = on_lclick
|
||||
on_upscroll = "increase_volume"
|
||||
on_downscroll = "decrease_volume"
|
||||
on_leftclick = "switch_mute"
|
||||
on_rightclick = on_leftclick
|
||||
|
||||
def init(self):
|
||||
self.create_mixer()
|
||||
|
@ -59,6 +59,9 @@ class Bitcoin(IntervalModule):
|
||||
"price_down": "▼",
|
||||
}
|
||||
|
||||
on_leftclick = "handle_leftclick"
|
||||
on_rightclick = "handle_rightclick"
|
||||
|
||||
_price_prev = 0
|
||||
|
||||
def _fetch_price_data(self):
|
||||
@ -122,8 +125,8 @@ class Bitcoin(IntervalModule):
|
||||
"color": color,
|
||||
}
|
||||
|
||||
def on_leftclick(self):
|
||||
def handle_leftclick(self):
|
||||
user_open(self.leftclick)
|
||||
|
||||
def on_rightclick(self):
|
||||
def handle_rightclick(self):
|
||||
user_open(self.rightclick)
|
||||
|
@ -28,8 +28,8 @@ class Clock(IntervalModule):
|
||||
color = "#ffffff"
|
||||
interval = 1
|
||||
current_format_id = 0
|
||||
on_scrollup = "next_format"
|
||||
on_scrolldown = "next_format"
|
||||
on_upscroll = ["scroll_format", 1]
|
||||
on_downscroll = ["scroll_format", -1]
|
||||
|
||||
def init(self):
|
||||
if self.format is None:
|
||||
@ -80,8 +80,5 @@ class Clock(IntervalModule):
|
||||
if self.color != "i3Bar":
|
||||
self.output["color"] = self.color
|
||||
|
||||
def next_format(self):
|
||||
self.current_format_id = (self.current_format_id + 1) % len(self.format)
|
||||
|
||||
def previous_format(self):
|
||||
self.current_format_id = (self.current_format_id - 1) % len(self.format)
|
||||
def scroll_format(self, step=1):
|
||||
self.current_format_id = (self.current_format_id + step) % len(self.format)
|
||||
|
@ -49,6 +49,11 @@ class Cmus(IntervalModule):
|
||||
"stopped": "◾",
|
||||
}
|
||||
|
||||
on_leftclick = "playpause"
|
||||
on_rightclick = "next_song"
|
||||
on_upscroll = "next_song"
|
||||
on_downscroll = "previous_song"
|
||||
|
||||
def _cmus_command(self, command):
|
||||
p = subprocess.Popen('cmus-remote --{command}'.format(command=command), shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
@ -108,7 +113,7 @@ class Cmus(IntervalModule):
|
||||
"color": self.color
|
||||
}
|
||||
|
||||
def on_leftclick(self):
|
||||
def playpause(self):
|
||||
status = self._query_cmus().get('status', '')
|
||||
if status == 'playing':
|
||||
self._cmus_command('pause')
|
||||
@ -117,11 +122,8 @@ class Cmus(IntervalModule):
|
||||
if status == 'stopped':
|
||||
self._cmus_command('play')
|
||||
|
||||
def on_rightclick(self):
|
||||
def next_song(self):
|
||||
self._cmus_command("next")
|
||||
|
||||
def on_upscroll(self):
|
||||
self._cmus_command("next")
|
||||
|
||||
def on_downscroll(self):
|
||||
def previous_song(self):
|
||||
self._cmus_command("prev")
|
||||
|
@ -8,20 +8,16 @@ class Module(SettingsBase):
|
||||
output = None
|
||||
position = 0
|
||||
|
||||
settings = ('on_lclick', "Callback called on left click",
|
||||
'on_rclick', "Callback called on right click",
|
||||
'on_scrollup', "Callback called on scrolling up",
|
||||
'on_scrolldown', "Callback called on scrolling down",
|
||||
settings = ('on_leftclick', "Callback called on left click (string)",
|
||||
'on_rightclick', "Callback called on right click (string)",
|
||||
'on_upscroll', "Callback called on scrolling up (string)",
|
||||
'on_downscroll', "Callback called on scrolling down (string)",
|
||||
)
|
||||
|
||||
# this allows for backward compatibility
|
||||
on_lclick = None
|
||||
on_rclick = None
|
||||
on_scrollup = None
|
||||
on_scrolldown = None
|
||||
# on_rclick = "on_rightclick"
|
||||
# on_scrollup = "on_upscroll"
|
||||
# on_scrolldown = "on_downscroll"
|
||||
on_leftclick = None
|
||||
on_rightclick = None
|
||||
on_upscroll = None
|
||||
on_downscroll = None
|
||||
|
||||
def registered(self, status_handler):
|
||||
"""Called when this module is registered with a status handler"""
|
||||
@ -39,42 +35,68 @@ class Module(SettingsBase):
|
||||
pass
|
||||
|
||||
def on_click(self, button):
|
||||
"""
|
||||
Maps a click event (include mousewheel events) with its associated callback.
|
||||
It then triggers the callback depending on the nature (ie type) of
|
||||
the callback variable:
|
||||
1. if null callback, do nothing
|
||||
2. if it's a python function
|
||||
3. if it's a method of the current module
|
||||
|
||||
To setup the callbacks, you can set the settings 'on_leftclick',
|
||||
'on_rightclick', 'on_upscroll', 'on_downscroll'.
|
||||
|
||||
For instance, you can test with:
|
||||
status.register("clock",
|
||||
format=[
|
||||
("Format 0",'Europe/London'),
|
||||
("%a %-d Format 1",'Europe/Dublin'),
|
||||
"%a %-d %b %X format 2",
|
||||
("%a %-d %b %X format 3", 'Europe/Paris'),
|
||||
],
|
||||
on_leftclick= ["urxvtc"] , # launch urxvtc on left click
|
||||
on_rightclick= ["scroll_format", 2] , # update format by steps of 2
|
||||
log_level=logging.DEBUG,
|
||||
)
|
||||
"""
|
||||
|
||||
def split_callback_and_args(cb):
|
||||
if isinstance(cb, list):
|
||||
return cb[0], cb[1:]
|
||||
else:
|
||||
return cb, []
|
||||
|
||||
cb = None
|
||||
if button == 1: # Left mouse button
|
||||
cb = self.on_lclick or "on_leftclick"
|
||||
cb = self.on_leftclick
|
||||
elif button == 3: # Right mouse button
|
||||
cb = self.on_rclick or "on_rightclick"
|
||||
cb = self.on_rightclick
|
||||
elif button == 4: # mouse wheel up
|
||||
cb = self.on_scrollup or "on_upscroll"
|
||||
cb = self.on_upscroll
|
||||
elif button == 5: # mouse wheel down
|
||||
cb = self.on_scrolldown or "on_downscroll"
|
||||
cb = self.on_downscroll
|
||||
else:
|
||||
self.logger.debug("Button not handled")
|
||||
self.logger.info("Button '%d' not handled yet." % (button))
|
||||
return
|
||||
|
||||
if not cb:
|
||||
self.logger.info("no cb attached")
|
||||
return
|
||||
else:
|
||||
cb, args = split_callback_and_args(cb)
|
||||
self.logger.debug("cb=%s args=%s" % (cb, args))
|
||||
|
||||
if callable(cb):
|
||||
return cb(self)
|
||||
elif hasattr(self, cb):
|
||||
return getattr(self, cb)()
|
||||
return getattr(self, cb)(*args)
|
||||
else:
|
||||
return run_through_shell(cb)
|
||||
return run_through_shell(cb, *args)
|
||||
|
||||
def move(self, position):
|
||||
self.position = position
|
||||
return self
|
||||
|
||||
def on_leftclick(self):
|
||||
pass
|
||||
|
||||
def on_rightclick(self):
|
||||
pass
|
||||
|
||||
def on_upscroll(self):
|
||||
pass
|
||||
|
||||
def on_downscroll(self):
|
||||
pass
|
||||
|
||||
|
||||
class IntervalModuleMeta(type):
|
||||
"""Add interval setting to `settings` attribute if it does not exist."""
|
||||
|
@ -431,7 +431,7 @@ def make_bar(percentage):
|
||||
def user_open(url_or_command):
|
||||
"""Open the specified paramater in the web browser if a URL is detected,
|
||||
othewrise pass the paramater to the shell as a subprocess. This function
|
||||
is inteded to bu used in on_leftclick()/on_rightclick() events.
|
||||
is inteded to bu used in on_leftclick/on_rightclick callbacks.
|
||||
|
||||
:param url_or_command: String containing URL or command
|
||||
"""
|
||||
|
@ -38,6 +38,8 @@ class Mail(IntervalModule):
|
||||
hide_if_null = True
|
||||
email_client = None
|
||||
|
||||
on_leftclick = "open_client"
|
||||
|
||||
def init(self):
|
||||
for backend in self.backends:
|
||||
pass
|
||||
@ -69,11 +71,8 @@ class Mail(IntervalModule):
|
||||
"color": color,
|
||||
}
|
||||
|
||||
def on_leftclick(self):
|
||||
def open_client(self):
|
||||
if self.email_client:
|
||||
retcode, _, stderr = run_through_shell(self.email_client)
|
||||
if retcode != 0 and stderr:
|
||||
self.logger.error(stderr)
|
||||
|
||||
def on_rightclick(self):
|
||||
self.run()
|
||||
|
@ -35,6 +35,8 @@ class ModsDeChecker(IntervalModule):
|
||||
cj = None
|
||||
logged_in = False
|
||||
|
||||
on_leftclick = "open_browser"
|
||||
|
||||
def init(self):
|
||||
self.cj = http.cookiejar.CookieJar()
|
||||
self.opener = urllib.request.build_opener(
|
||||
@ -94,5 +96,5 @@ class ModsDeChecker(IntervalModule):
|
||||
return True
|
||||
return False
|
||||
|
||||
def on_leftclick(self):
|
||||
def open_browser(self):
|
||||
webbrowser.open_new_tab("http://forum.mods.de/bb/")
|
||||
|
@ -50,6 +50,10 @@ class MPD(IntervalModule):
|
||||
color = "#FFFFFF"
|
||||
text_len = 25
|
||||
truncate_fields = ("title", "album", "artist")
|
||||
on_leftclick = "switch_playpause"
|
||||
on_rightclick = "next_song"
|
||||
on_upscroll = on_rightclick
|
||||
on_downscroll = "previous_song"
|
||||
|
||||
def _mpd_command(self, sock, command):
|
||||
try:
|
||||
@ -101,26 +105,20 @@ class MPD(IntervalModule):
|
||||
"color": self.color,
|
||||
}
|
||||
|
||||
def on_leftclick(self):
|
||||
def switch_playpause(self):
|
||||
try:
|
||||
self._mpd_command(self.s, "%s" %
|
||||
("play" if self._mpd_command(self.s, "status")["state"] in ["pause", "stop"] else "pause"))
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
def on_rightclick(self):
|
||||
def next_song(self):
|
||||
try:
|
||||
self._mpd_command(self.s, "next")
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
def on_upscroll(self):
|
||||
try:
|
||||
self._mpd_command(self.s, "next")
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
def on_downscroll(self):
|
||||
def previous_song(self):
|
||||
try:
|
||||
self._mpd_command(self.s, "previous")
|
||||
except Exception as e:
|
||||
|
@ -105,6 +105,7 @@ class Network(IntervalModule):
|
||||
color_down = "#FF0000"
|
||||
detached_down = True
|
||||
unknown_up = False
|
||||
on_leftclick = "nm-connection-editor"
|
||||
|
||||
def init(self):
|
||||
if self.interface not in netifaces.interfaces() and not self.detached_down:
|
||||
@ -174,6 +175,3 @@ class Network(IntervalModule):
|
||||
"color": color,
|
||||
"instance": self.interface
|
||||
}
|
||||
|
||||
def on_leftclick(self):
|
||||
subprocess.Popen(["nm-connection-editor"])
|
||||
|
@ -54,6 +54,8 @@ class NowPlaying(IntervalModule):
|
||||
color = "#FFFFFF"
|
||||
|
||||
old_player = None
|
||||
on_leftclick = "playpause"
|
||||
on_rightclick = "next_song"
|
||||
|
||||
def find_player(self):
|
||||
players = [a for a in dbus.SessionBus().get_object("org.freedesktop.DBus", "/org/freedesktop/DBus").ListNames() if a.startswith("org.mpris.MediaPlayer2.")]
|
||||
@ -111,8 +113,8 @@ class NowPlaying(IntervalModule):
|
||||
"color": self.color,
|
||||
}
|
||||
|
||||
def on_leftclick(self):
|
||||
def playpause(self):
|
||||
self.get_player().PlayPause()
|
||||
|
||||
def on_rightclick(self):
|
||||
def next_song(self):
|
||||
self.get_player().Next()
|
||||
|
@ -153,6 +153,7 @@ class ParcelTracker(IntervalModule):
|
||||
required = ("instance",)
|
||||
|
||||
format = "{name}:{progress}"
|
||||
on_leftclick = "open_browser"
|
||||
|
||||
@require(internet)
|
||||
def run(self):
|
||||
@ -166,5 +167,5 @@ class ParcelTracker(IntervalModule):
|
||||
"instance": self.name,
|
||||
}
|
||||
|
||||
def on_leftclick(self):
|
||||
def open_browser(self):
|
||||
webbrowser.open_new_tab(self.instance.get_url())
|
||||
|
@ -27,6 +27,11 @@ class Pianobar(IntervalModule):
|
||||
required = ("format", "songfile", "ctlfile")
|
||||
color = "#FFFFFF"
|
||||
|
||||
on_leftclick = "playpause"
|
||||
on_rightclick = "next_song"
|
||||
on_upscroll = "increase_volume"
|
||||
on_downscroll = "decrease_volume"
|
||||
|
||||
def run(self):
|
||||
with open(self.songfile, "r") as f:
|
||||
contents = f.readlines()
|
||||
@ -39,14 +44,14 @@ class Pianobar(IntervalModule):
|
||||
"color": self.color
|
||||
}
|
||||
|
||||
def on_leftclick(self):
|
||||
def playpause(self):
|
||||
open(self.ctlfile, "w").write("p")
|
||||
|
||||
def on_rightclick(self):
|
||||
def next_song(self):
|
||||
open(self.ctlfile, "w").write("n")
|
||||
|
||||
def on_upscroll(self):
|
||||
def increase_volume(self):
|
||||
open(self.ctlfile, "w").write(")")
|
||||
|
||||
def on_downscroll(self):
|
||||
def decrease_volume(self):
|
||||
open(self.ctlfile, "w").write("(")
|
||||
|
@ -42,6 +42,9 @@ class Pomodoro(IntervalModule):
|
||||
break_duration = 5 * 60
|
||||
long_break_duration = 15 * 60
|
||||
|
||||
on_rightclick = "stop"
|
||||
on_leftclick = "start"
|
||||
|
||||
def init(self):
|
||||
# state could be either running/break or stopped
|
||||
self.state = 'stopped'
|
||||
@ -90,12 +93,12 @@ class Pomodoro(IntervalModule):
|
||||
'color': color
|
||||
}
|
||||
|
||||
def on_leftclick(self):
|
||||
def start(self):
|
||||
self.state = 'running'
|
||||
self.time = datetime.now() + timedelta(seconds=self.pomodoro_duration)
|
||||
self.breaks = 0
|
||||
|
||||
def on_rightclick(self):
|
||||
def stop(self):
|
||||
self.state = 'stopped'
|
||||
self.time = None
|
||||
|
||||
|
@ -50,6 +50,11 @@ class PulseAudio(Module, ColorRangeModule):
|
||||
bar_type = 'vertical'
|
||||
vertical_bar_width = 2
|
||||
|
||||
on_rightclick = "switch_mute"
|
||||
on_leftclick = "pavucontrol"
|
||||
on_upscroll = "increase_volume"
|
||||
on_downscroll = "decrease_volume"
|
||||
|
||||
def init(self):
|
||||
"""Creates context, when context is ready context_notify_cb is called"""
|
||||
# Wrap callback methods in appropriate ctypefunc instances so
|
||||
@ -155,10 +160,7 @@ class PulseAudio(Module, ColorRangeModule):
|
||||
volume_bar=volume_bar),
|
||||
}
|
||||
|
||||
def on_leftclick(self):
|
||||
subprocess.Popen(["pavucontrol"])
|
||||
|
||||
def on_rightclick(self):
|
||||
def switch_mute(self):
|
||||
if self.has_amixer:
|
||||
command = "amixer -q -D pulse sset Master "
|
||||
if self.currently_muted:
|
||||
@ -167,12 +169,12 @@ class PulseAudio(Module, ColorRangeModule):
|
||||
command += 'mute'
|
||||
subprocess.Popen(command.split())
|
||||
|
||||
def on_upscroll(self):
|
||||
def increase_volume(self):
|
||||
if self.has_amixer:
|
||||
command = "amixer -q -D pulse sset Master %s%%+" % self.step
|
||||
subprocess.Popen(command.split())
|
||||
|
||||
def on_downscroll(self):
|
||||
def decrease_volume(self):
|
||||
if self.has_amixer:
|
||||
command = "amixer -q -D pulse sset Master %s%%-" % self.step
|
||||
subprocess.Popen(command.split())
|
||||
|
@ -39,6 +39,7 @@ class pyLoad(IntervalModule):
|
||||
captcha_false = ""
|
||||
download_true = "Downloads enabled"
|
||||
download_false = "Downloads disabled"
|
||||
on_leftclick = "open_webbrowser"
|
||||
|
||||
def _rpc_call(self, method, data=None):
|
||||
if not data:
|
||||
@ -83,5 +84,5 @@ class pyLoad(IntervalModule):
|
||||
"instance": self.address,
|
||||
}
|
||||
|
||||
def on_leftclick(self):
|
||||
def open_webbrowser(self):
|
||||
webbrowser.open_new_tab(self.address)
|
||||
|
@ -61,6 +61,9 @@ class Reddit(IntervalModule):
|
||||
"no_mail": "",
|
||||
}
|
||||
|
||||
on_leftclick = "open_permalink"
|
||||
on_click = "open_link"
|
||||
|
||||
_permalink = ""
|
||||
_url = ""
|
||||
|
||||
@ -133,8 +136,8 @@ class Reddit(IntervalModule):
|
||||
"color": color,
|
||||
}
|
||||
|
||||
def on_leftclick(self):
|
||||
def open_permalink(self):
|
||||
user_open(self._permalink)
|
||||
|
||||
def on_rightclick(self):
|
||||
def open_link(self):
|
||||
user_open(self._url)
|
||||
|
@ -23,6 +23,9 @@ class Spotify(Module):
|
||||
("color", "color of the output"),
|
||||
)
|
||||
|
||||
on_leftclick = "switch_playpause"
|
||||
on_rightclick = "next_song"
|
||||
|
||||
def main_loop(self):
|
||||
""" Mainloop blocks so we thread it."""
|
||||
self.player = Playerctl.Player()
|
||||
@ -62,8 +65,8 @@ class Spotify(Module):
|
||||
"color": self.color
|
||||
}
|
||||
|
||||
def on_leftclick(self):
|
||||
def switch_playpause(self):
|
||||
self.player.play_pause()
|
||||
|
||||
def on_rightclick(self):
|
||||
def next_song(self):
|
||||
self.player.next()
|
||||
|
@ -1,5 +1,3 @@
|
||||
import subprocess
|
||||
|
||||
from i3pystatus import Module
|
||||
|
||||
|
||||
@ -11,14 +9,10 @@ class Text(Module):
|
||||
settings = (
|
||||
"text",
|
||||
("color", "HTML color code #RRGGBB"),
|
||||
("cmd_leftclick", "Shell command to execute on left click"),
|
||||
("cmd_rightclick", "Shell command to execute on right click"),
|
||||
)
|
||||
required = ("text",)
|
||||
|
||||
color = None
|
||||
cmd_leftclick = "test"
|
||||
cmd_rightclick = "test"
|
||||
|
||||
def init(self):
|
||||
self.output = {
|
||||
@ -26,9 +20,3 @@ class Text(Module):
|
||||
}
|
||||
if self.color:
|
||||
self.output["color"] = self.color
|
||||
|
||||
def on_leftclick(self):
|
||||
subprocess.call(self.cmd_leftclick, shell=True)
|
||||
|
||||
def on_rightclick(self):
|
||||
subprocess.call(self.cmd_rightclick, shell=True)
|
||||
|
Loading…
Reference in New Issue
Block a user