Notifications über Scroll Lock
Seit kurzem besitze ich eine CM Storm Quick Fire Rapid-I, eine mechanische Tastatur mit hintergrundbeleuchteten Tasten. Eigentlich unnötig, sieht aber toll aus. Nur ein paar Tasten leuchten nicht¹: Caps Lock, Scroll Lock und Druck. Bei diesen Tasten wird die LED nämlich gleichzeitig als Indikator genutzt.
Bei Caps Lock macht das noch durchaus Sinn, aber ich habe in meinem Leben noch nie die Scroll Lock LED leuchten gesehen (oder die Taste genutzt). Also was macht man damit? Man benutzt sie für Benachrichtigungen!
Umgebung
In diesem Artikel setze ich ein Linux mit X-Server und awesome als Window Manager voraus. Man sollte das aber auch leicht auf andere (Linux-)Umgebungen übertragen können.
Idee
Wenn etwas meine Aufmerksamkeit erfordert, sollte es den Urgency Window Manager Hint setzen. In awesome wird der entsprechende Client dann bereits hervorgehoben. Nun soll zusätzlich noch die Scroll Lock LED blinken und bei einem Druck dieser Taste zum entsprechenden Client wechseln.
Umsetzung
Das Wechseln zum Client mit einem Urgency Hint lässt sich relativ leicht realisieren, indem man folgende Zeile in seine Key Bindings aufnimmt:
awful.key({ }, "Scroll_Lock", awful.client.urgent.jumpto)
Das Blinken habe ich über Signals und einen Timer realisiert: Ändert sich der Urgency Hint bei einem Client, wird das property::urgent
Signal gesendet. Dort wird dann je nachdem, ob es noch einen Client mit Urgency Hint gibt, ein Timer gestartet oder stoppt, der die LED blinken lässt. Dies wiederum wird mittels xset realisiert.
Der fertige Code sieht schließlich so aus:
local urgent_notify_timer = timer({ timeout = 1 })
local urgent_led_status = false
urgent_notify_timer:connect_signal("timeout", function()
if urgent_led_status then
awful.util.spawn("xset -led named \"Scroll Lock\"")
urgent_led_status = false
else
awful.util.spawn("xset led named \"Scroll Lock\"")
urgent_led_status = true
end
end)
client.connect_signal("property::urgent", function(c)
if c.urgent then
-- if client already has focus, ignore
if c == client.focus then return end
-- start timer, ignore if already running
urgent_notify_timer:start()
elseif awful.client.urgent.get() == nil then
-- no urgent clients left, stop timer, turn off LED and reset LED state
urgent_notify_timer:stop()
awful.util.spawn("xset -led named \"Scroll Lock\"")
urgent_led_status = false
end
end)
Die Blinkgeschwindigkeit ist über den Timeout festgelegt und lässt sich leicht auf die eigenen Bedürfnisse anpassen. Zu beachten war noch, dass Clients auch den Urgency Hint setzen können, während sie bereits den Fokus haben. Dieser Hint wird erst entfernt, wenn der Client den Fokus wieder verliert.
Der Code ist nur schnell hingeschrieben und könnte noch etwas aufgeräumt, vielleicht sogar in ein eigenes Modul verschoben werden. Aber es funktioniert und das hat mir erst einmal gereicht.
____________
¹ Und damit meine ich nicht die chronisch defekten LEDs. Leider gehen die wohl recht schnell kaputt, aber gibt wenig Alternativen, wenn man ein TKL mit Cherry MX für den Preis haben möchte.