- keymap.connect('state-changed', self.update_indicator)
- self.update_indicator(keymap)
-
- menu = Gtk.Menu()
- items = {
- 'caps' : Gtk.MenuItem.new_with_label('Caps Lock'),
- 'num' : Gtk.MenuItem.new_with_label('Num Lock'),
- 'scr' : Gtk.MenuItem.new_with_label('Scroll Lock')
- }
- menu.append(items['caps'])
- menu.append(items['num'])
- menu.append(items['scr'])
-
- items['caps'].connect('activate', self.send_keypress, 'Caps_Lock')
- items['num' ].connect('activate', self.send_keypress, 'Num_Lock')
- items['scr' ].connect('activate', self.send_keypress, 'Scroll_Lock')
-
- self.indicator.set_menu(menu)
- menu.show_all()
-
- def update_indicator(self, keymap):
- label = '⚫' if keymap.get_caps_lock_state() else '⚪'
- label += self.locks['caps'] + ' '
- label += '⚫' if keymap.get_num_lock_state() else '⚪'
- label += self.locks['num'] + ' '
- label += '⚫' if keymap.get_scroll_lock_state() else '⚪'
- label += self.locks['scr']
- self.indicator.set_label(label, '')
-
- def send_keypress(self, menuitem, keystroke):
- subprocess.call(['xdotool', 'key', keystroke])
+ keymap.connect('state-changed', self.update_indicator, order)
+ self.update_indicator(keymap, order)
+ self.create_menu(xdotool, order)
+
+ def create_menu(self, xdotool, order):
+ xdotool = xdotool or shutil.which('xdotool')
+ def send_keypress(menuitem, keystroke):
+ subprocess.call([xdotool, 'key', keystroke])
+ def new_menu_item(itemtype):
+ if itemtype == 'N':
+ item = Gtk.MenuItem.new_with_label(_('Num Lock'))
+ item.connect('activate', send_keypress, 'Num_Lock')
+ elif itemtype == 'C':
+ item = Gtk.MenuItem.new_with_label(_('Caps Lock'))
+ item.connect('activate', send_keypress, 'Caps_Lock')
+ elif itemtype == 'S':
+ item = Gtk.MenuItem.new_with_label(_('Scroll Lock'))
+ item.connect('activate', send_keypress, 'Scroll_Lock')
+ else:
+ raise ValueError('Invalid itemtype')
+ return item
+
+ for i in order:
+ menu = Gtk.Menu()
+
+ if xdotool and os.access(xdotool, os.X_OK) and os.path.isfile(xdotool):
+ menu.append(new_menu_item(i))
+
+ quit_item = Gtk.MenuItem.new_with_label(_('Quit'))
+ menu.append(quit_item)
+ quit_item.connect('activate', Gtk.main_quit)
+
+ self.indicators[i].set_menu(menu)
+ menu.show_all()
+
+ def update_indicator(self, keymap, order):
+ 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')
+
+ icon = os.path.join(ICON_FOLDER, '-'.join([APP_NAME, i, 'on.svg' if state else 'off.svg']))
+ self.indicators[i].set_icon(icon)
+
+
+ def validate_order(self, order):
+ order = order.upper()
+ for i in order:
+ if i not in ['N', 'C', 'S']:
+ raise ValueError('Illegal character in ORDER. '
+ '(Choices: [N, C, S])')
+ if len(order) != len(set(order)):
+ raise ValueError('Repeated character in ORDER. '
+ 'Please specify each lock at most once.')
+ if 'S' in order and Gtk.check_version(3, 18, 0) is not None:
+ # Silently drop Scroll lock if GTK <= 3.18
+ order.remove('S')
+