From: Adrian Iain Lam Date: Mon, 29 Aug 2016 04:06:27 +0000 (+0800) Subject: Add feature: quit button, customize lock keys display X-Git-Tag: v0.99~4 X-Git-Url: https://adrianiainlam.tk/git/?a=commitdiff_plain;h=170ff3962573a8e5ff03539732d59ef3fe05dbd0;p=indicator-keyboard-led.git Add feature: quit button, customize lock keys display --- diff --git a/README.md b/README.md index 345b077..581faca 100644 --- a/README.md +++ b/README.md @@ -19,10 +19,6 @@ the respective item in the menu. ![indicator short][sc3] Alternative (short) appearance of the indicator. -[sc1]: screenshots/sc1.png -[sc2]: screenshots/sc2.png -[sc3]: screenshots/sc3.png - ## Dependencies - Python 3 (*) - GTK+ 3 (*) @@ -40,7 +36,8 @@ distributions. To install the rest, run: 1. Install the dependencies listed above. 2. Clone this repository. 3. Add the script as a startup application. (Use option `--short` for short - appearance if desired.) + appearance; use option `--order` to customize the order of the locks + displayed. See [Examples](#examples)) 4. Run the script manually for the first time. (Alternatively, log out and log in again.) 5. The indicator should be shown at the top right corner, with a filled circle @@ -49,6 +46,32 @@ distributions. To install the rest, run: 6. Clicking on the indicator should result in a menu with the three locks. Clicking on the menu item would cause the corresponding lock to toggle. +## Examples + +![indicator default][sc1] +Default appearance. `python3 indicator-keyboard-led.py` + +![indicator short][sc3] +Short appearance. `python3 indicator-keyboard-led.py --short` + +![indicator CNS][sc4] +Order changed to Caps Num Scroll. +`python3 indicator-keyboard-led.py --order CNS` + +![indicator NC][sc5] +Hide Scroll lock. `python3 indicator-keyboard-led.py --order NC` + +![indicator C short][sc6] +Show Caps lock only, short appearance. +`python3 indicator-keyboard-led.py --short --order C` + +[sc1]: screenshots/sc1.png +[sc2]: screenshots/sc2.png +[sc3]: screenshots/sc3.png +[sc4]: screenshots/sc4.png +[sc5]: screenshots/sc5.png +[sc6]: screenshots/sc6.png + ## Known bugs It seems to be a common problem that Scroll Lock is not usable in Ubuntu. diff --git a/indicator-keyboard-led.py b/indicator-keyboard-led.py index 4d73f14..42b4161 100755 --- a/indicator-keyboard-led.py +++ b/indicator-keyboard-led.py @@ -30,6 +30,7 @@ import signal import subprocess from os import path import argparse +import sys import gi gi.require_version('Gdk', '3.0') gi.require_version('Gtk', '3.0') @@ -37,60 +38,83 @@ gi.require_version('AppIndicator3', '0.1') from gi.repository import Gdk, Gtk, AppIndicator3 class IndicatorKeyboardLED: - locks = { 'num': 'Num', 'caps': 'Caps', 'scr': 'Scroll' } + locks = { 'N': 'Num', 'C': 'Caps', 'S': 'Scroll' } - def __init__(self, short=False): + def __init__(self, short=False, order='NCS'): self.indicator = AppIndicator3.Indicator.new( 'indicator-keyboard-led', path.join(path.dirname(path.realpath(__file__)), 'icon.svg'), AppIndicator3.IndicatorCategory.APPLICATION_STATUS) self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE) - + if short: - self.locks = { 'num': 'N', 'caps': 'C', 'scr': 'S' } + self.locks = { 'N': 'N', 'C': 'C', 'S': 'S' } keymap = Gdk.Keymap.get_default() - keymap.connect('state-changed', self.update_indicator) - self.update_indicator(keymap) + keymap.connect('state-changed', self.update_indicator, order) + self.update_indicator(keymap, order) menu = Gtk.Menu() items = { - 'num' : Gtk.MenuItem.new_with_label('Num Lock'), - 'caps' : Gtk.MenuItem.new_with_label('Caps Lock'), - 'scr' : Gtk.MenuItem.new_with_label('Scroll Lock') + 'N': Gtk.MenuItem.new_with_label('Num Lock'), + 'C': Gtk.MenuItem.new_with_label('Caps Lock'), + 'S': Gtk.MenuItem.new_with_label('Scroll Lock') } - menu.append(items['num']) - menu.append(items['caps']) - menu.append(items['scr']) + items['N'].connect('activate', self.send_keypress, 'Num_Lock') + items['C'].connect('activate', self.send_keypress, 'Caps_Lock') + items['S'].connect('activate', self.send_keypress, 'Scroll_Lock') + + for i in order: + menu.append(items[i]) - items['num' ].connect('activate', self.send_keypress, 'Num_Lock') - items['caps'].connect('activate', self.send_keypress, 'Caps_Lock') - items['scr' ].connect('activate', self.send_keypress, 'Scroll_Lock') + quit_item = Gtk.MenuItem.new_with_label('Quit') + menu.append(Gtk.SeparatorMenuItem()) + menu.append(quit_item) + quit_item.connect('activate', Gtk.main_quit) self.indicator.set_menu(menu) menu.show_all() - def update_indicator(self, keymap): - label = '⚫' if keymap.get_num_lock_state() else '⚪' - label += self.locks['num'] + ' ' - label += '⚫' if keymap.get_caps_lock_state() else '⚪' - label += self.locks['caps'] + ' ' - label += '⚫' if keymap.get_scroll_lock_state() else '⚪' - label += self.locks['scr'] - self.indicator.set_label(label, '') + def update_indicator(self, keymap, order): + labels = [] + for i in order: + if i == 'N': + state = keymap.get_num_lock_state() + elif i == 'C': + state = keymap.get_caps_lock_state() + elif i == 'S': + state = keymap.get_scroll_lock_state() + else: + raise ValueError('Invalid value in ORDER') + labels += [('⚫' if state else '⚪') + self.locks[i]] + self.indicator.set_label(' '.join(labels), '') def send_keypress(self, menuitem, keystroke): subprocess.call(['xdotool', 'key', keystroke]) +def validate_order(args): + args.order = args.order.upper() + for i in args.order: + if i not in ['N', 'C', 'S']: + sys.exit('Illegal character in ORDER. (Choices: [N, C, S])') + if len(args.order) != len(set(args.order)): + sys.exit('Repeated character in ORDER. ' + 'Please specify each lock at most once.') + if __name__ == '__main__': signal.signal(signal.SIGINT, lambda signum, frame: Gtk.main_quit()) - + parser = argparse.ArgumentParser( - description='indicator-keyboard-led - simulate keyboard lock keys LED') - parser.add_argument('-s', '--short', dest='short', action='store_true', + description='indicator-keyboard-led - simulate keyboard lock keys LED', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('-s', '--short', action='store_true', help='use short label, i.e. ⚫N ⚫C ⚫S instead of ⚫Num ⚫Caps ⚫Scroll', required=False) + parser.add_argument('-o', '--order', required=False, default='NCS', + help='specify the order of the locks displayed, e.g. CSN for ' + '⚫Caps ⚫Scroll ⚫Num, or NC for ⚫Num ⚫Caps without Scroll lock') args = parser.parse_args() - - IndicatorKeyboardLED(short=args.short) + validate_order(args) + + IndicatorKeyboardLED(short=args.short, order=args.order) Gtk.main() diff --git a/screenshots/sc2.png b/screenshots/sc2.png index 67fdd98..228adee 100644 Binary files a/screenshots/sc2.png and b/screenshots/sc2.png differ diff --git a/screenshots/sc4.png b/screenshots/sc4.png new file mode 100644 index 0000000..8852e62 Binary files /dev/null and b/screenshots/sc4.png differ diff --git a/screenshots/sc5.png b/screenshots/sc5.png new file mode 100644 index 0000000..ca10484 Binary files /dev/null and b/screenshots/sc5.png differ diff --git a/screenshots/sc6.png b/screenshots/sc6.png new file mode 100644 index 0000000..b7db313 Binary files /dev/null and b/screenshots/sc6.png differ