diff --git a/xkeysnail-config/gui/kinto-gui.py b/xkeysnail-config/gui/kinto-gui.py
new file mode 100755
index 0000000..f3dcec8
--- /dev/null
+++ b/xkeysnail-config/gui/kinto-gui.py
@@ -0,0 +1,817 @@
+#!/usr/bin/env python3
+
+import gi,os,time,fcntl,argparse,re
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk,Gdk,GdkPixbuf
+from gi.repository import Vte,GLib
+from subprocess import Popen,PIPE,CalledProcessError
+
+class MyWindow(Gtk.Window):
+
+ label = Gtk.Label()
+ label.set_alignment(1, 0)
+ ostype = os.environ.get('XDG_CURRENT_DESKTOP')
+
+ kinto_status = Popen("while :; do clear; systemctl is-active xkeysnail; sleep 2; done", stdout=PIPE, shell=True)
+
+ winkb = Gtk.RadioMenuItem(label='Windows')
+ mackb = Gtk.RadioMenuItem(label='Apple',group=winkb)
+ chromekb = Gtk.RadioMenuItem(label='Chromebook',group=winkb)
+ ibmkb = Gtk.RadioMenuItem(label='IBM (No Super/Win key)',group=winkb)
+ winmackb = Gtk.RadioMenuItem(label='Windows & Apple*',group=winkb)
+
+ mackb.signal_id = 0
+ winkb.signal_id = 0
+ chromekb.signal_id = 0
+ ibmkb.signal_id = 0
+ winmackb.signal_id = 0
+
+ menuitem_auto = Gtk.CheckMenuItem(label="Autostart")
+ menuitem_auto.signal_id = 0
+ menuitem_enable = Gtk.CheckMenuItem(label="Enable")
+ menuitem_enable.signal_id = 0
+
+ def __init__(self):
+
+ Gtk.Window.__init__(self, title="Kinto.sh")
+ # self.set_icon_from_file(os.environ['HOME']+'/.config/kinto/kinto-color.svg')
+ # self.set_gravity(Gdk.Gravity.NORTH_WEST)
+ self.set_size_request(600, 360)
+
+ global restartsvc
+ restartsvc = False
+
+ homedir = os.path.expanduser("~")
+ self.kconfig = homedir+"/.config/kinto/kinto.py"
+
+ path = os.environ['HOME']+'/.config/kinto/kinto-color.svg'
+ width = 256
+ height = 256
+ preserve_aspect_ratio = True
+
+ pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, width, height, preserve_aspect_ratio)
+ # image = Gtk.Image()
+ # image.set_from_pixbuf(pixbuf)
+ self.set_default_icon_list([pixbuf])
+
+ # self.button = Gtk.Button("Do The Command")
+ # self.button2 = Gtk.Button("End Command")
+ # self.InputToTerm(self.cmdbytes)
+ # self.command2 = "send \003; echo 'hello'\n"
+ # # expect -c "send \003;"
+ # self.cmdbytes2 = str.encode(self.command2)
+ # self.button.connect("clicked", self.InputToTerm, self.cmdbytes)
+ # self.button2.connect("clicked", self.InputToTerm, self.cmdbytes2)
+
+ parser = argparse.ArgumentParser()
+
+ # parser.add_argument('-b', type=int, required=False, help="")
+ # parser.add_argument('-e', type=int, default=2, help="")
+ parser.add_argument('-d', dest='debug', action='store_true', help="runs kinto in debug mode")
+ parser.add_argument('--debug', dest='debug', action='store_true', help="runs kinto in debug mode")
+
+ args = parser.parse_args()
+
+ global terminal
+ terminal = Vte.Terminal()
+ terminal.spawn_sync(
+ Vte.PtyFlags.DEFAULT,
+ os.environ['HOME']+'/.config/kinto',
+ ["/bin/bash"],
+ [],
+ GLib.SpawnFlags.DO_NOT_REAP_CHILD,
+ None,
+ None,
+ )
+
+ if args.debug:
+ # print("run debug")
+ self.command = "sudo systemctl stop xkeysnail && sudo xkeysnail ~/.config/kinto/kinto.py\n"
+ else:
+ self.command = "journalctl -f --unit=xkeysnail.service -b\n"
+
+ self.cmdbytes = str.encode(self.command)
+ self.InputToTerm(self.cmdbytes)
+
+ grid = Gtk.Grid()
+ grid.modify_bg(Gtk.StateFlags.NORMAL, Gdk.color_parse("#2d303b"))
+ self.add(grid)
+
+ menubar = Gtk.MenuBar()
+ # menubar.set_hexpand(True)
+ grid.attach(menubar, 0, 0, 1, 1)
+ # grid.add(menubar)
+
+ # grid.add(self.button)
+ # grid.add(self.button2)
+ # grid.add(self.status)
+ # grid.attach(self.button, 0, 1, 1, 1)
+ # grid.attach(self.button2, 1, 1, 1, 1)
+
+ scroller = Gtk.ScrolledWindow()
+ # scroller.set_size_request(200,100)
+ scroller.set_hexpand(True)
+ scroller.set_vexpand(True)
+ scroller.add(terminal)
+ grid.attach(scroller, 0, 1, 1, 1)
+ # grid.add(scroller)
+ # grid.attach(scroller, 0, 0, 2, 2)
+ grid.attach_next_to(self.label, scroller, Gtk.PositionType.BOTTOM, 2, 1)
+ # grid.attach_next_to(self.label2, self.label, Gtk.PositionType.RIGHT, 2, 1)
+
+ # three labels
+ label_top_left = Gtk.Label(label="Top left")
+ another = Gtk.Label(label="another")
+ # label_top_right = Gtk.Label(label="This is Top Right")
+ # label_bottom = Gtk.Label(label="This is Bottom")
+
+ # some space between the columns of the grid
+ # grid.set_column_spacing(20)
+
+ # in the grid:
+ # attach the first label in the top left corner
+ # grid.add(label_top_left)
+ # grid.attach(label_top_left, 0, 0, 1, 1)
+ # attach the second label
+ # grid.attach(label_top_right, 1, 0, 1, 1)
+ # attach the third label below the first label
+ # grid.attach_next_to(label_bottom, label_top_left, Gtk.PositionType.BOTTOM, 2, 1)
+ # grid.attach_next_to(menubar, label_top_left, Gtk.PositionType.BOTTOM, 2, 1)
+
+ # sw = Gtk.ScrolledWindow()
+ # self.label.set_alignment(0, 0)
+ # self.label.set_selectable(True)
+ # self.label.set_line_wrap(True)
+ # self.label.set_max_width_chars(150)
+ # # sw.set_size_request(400,300)
+ # sw.set_hexpand(True)
+ # sw.set_vexpand(True)
+ # sw.add_with_viewport(self.label)
+ # # self.add(sw)
+ # # grid.add(sw)
+ # # grid.add(self.status)
+ # grid.attach(sw, 0, 0, 2, 2)
+ # # sub_proc = Popen("journalctl -f --unit=xkeysnail.service -b", stdout=PIPE, shell=True)
+ # # sub_outp = ""
+
+ with open(self.kconfig) as configfile:
+ autostart_line = configfile.read().split('\n')[1]
+
+ # Autostart
+ if "autostart = true" in autostart_line.casefold():
+ autostart_bool = True
+
+ if autostart_bool:
+ # Popen(['sudo', 'systemctl','restart','xkeysnail'])
+ self.menuitem_auto.set_active(True)
+ self.menuitem_auto.signal_id = self.menuitem_auto.connect('activate',self.setAutostart,False)
+ else:
+ self.menuitem_auto.set_active(False)
+ self.menuitem_auto.signal_id = self.menuitem_auto.connect('activate',self.setAutostart,True)
+
+ menuitem_file = Gtk.MenuItem(label="File")
+ menubar.append(menuitem_file)
+ submenu_file = Gtk.Menu()
+ menuitem_file.set_submenu(submenu_file)
+ submenu_file.append(self.menuitem_auto)
+ submenu_file.append(self.menuitem_enable)
+ # self.menuitem_enable.connect('activate', self.setEnable)
+ menuitem_restart = Gtk.MenuItem(label="Restart")
+ menuitem_restart.connect('activate',self.runRestart)
+ submenu_file.append(menuitem_restart)
+
+ menuitem_quit = Gtk.MenuItem(label="Quit")
+ submenu_file.append(menuitem_quit)
+ menuitem_quit.connect('activate', self.on_menu_quit)
+
+ menuitem_edit = Gtk.MenuItem(label="Edit")
+ menubar.append(menuitem_edit)
+ submenu_edit = Gtk.Menu()
+ menuitem_edit.set_submenu(submenu_edit)
+ edititem_tweaks = Gtk.MenuItem("Tweaks")
+ edititem_tweaks.connect('activate',self.setTweaks)
+ submenu_edit.append(edititem_tweaks)
+ edititem_config = Gtk.MenuItem("Kinto Config (shortcuts)")
+ edititem_config.connect('activate',self.setConfig)
+ submenu_edit.append(edititem_config)
+ edititem_service = Gtk.MenuItem("Kinto Service")
+ edititem_service.connect('activate',self.setService)
+ submenu_edit.append(edititem_service)
+ edititem_shortcuts = Gtk.MenuItem("System Shortcuts")
+ edititem_shortcuts.connect('activate',self.setSysKB)
+ submenu_edit.append(edititem_shortcuts)
+ edititem_language = Gtk.MenuItem("Change Language")
+ edititem_language.connect('activate',self.setRegion)
+ submenu_edit.append(edititem_language)
+
+ keyboards = Gtk.MenuItem(label="Keyboard")
+ keyboards.connect('activate',self.refresh)
+ menubar.append(keyboards)
+
+ # tweaks = Gtk.MenuItem(label="Tweaks")
+ # menubar.append(tweaks)
+ # submenu_tweaks = Gtk.Menu()
+ # tweaks.set_submenu(submenu_tweaks)
+ # tweakitem_rightmod = Gtk.CheckMenuItem("AltGr on Right Cmd")
+ # submenu_tweaks.append(tweakitem_rightmod)
+ # tweakitem_vsc2st3 = Gtk.CheckMenuItem("ST3 hotkeys for VS Code")
+ # submenu_tweaks.append(tweakitem_vsc2st3)
+ # tweakitem_caps2esc = Gtk.CheckMenuItem("Capslock is Escape when tapped, Cmd when held")
+ # submenu_tweaks.append(tweakitem_caps2esc)
+ # tweakitem_caps2cmd = Gtk.CheckMenuItem("Capslock is Cmd")
+ # submenu_tweaks.append(tweakitem_caps2cmd)
+
+ menuitem_help = Gtk.MenuItem(label="Help")
+ menubar.append(menuitem_help)
+ submenu_help = Gtk.Menu()
+ helpitem_debug = Gtk.MenuItem(label="Debug")
+ helpitem_debug.connect('activate',self.runDebug)
+ submenu_help.append(helpitem_debug)
+ helpitem_support = Gtk.MenuItem("Support")
+ helpitem_support.connect('activate',self.openSupport)
+ submenu_help.append(helpitem_support)
+ menuitem_help.set_submenu(submenu_help)
+ helpitem_about = Gtk.MenuItem("About")
+ helpitem_about.connect('activate',self.runAbout)
+ submenu_help.append(helpitem_about)
+
+ menu = Gtk.Menu()
+ keyboards.set_submenu(menu)
+
+ self.refreshKB()
+
+ self.mackb.signal_id = self.mackb.connect('activate',self.setKB,"mac")
+ self.winkb.signal_id = self.winkb.connect('activate',self.setKB,"win")
+ self.chromekb.signal_id = self.chromekb.connect('activate',self.setKB,"chrome")
+ self.ibmkb.signal_id = self.ibmkb.connect('activate',self.setKB,"ibm")
+ self.winmackb.signal_id = self.winmackb.connect('activate',self.setKB,"winmac")
+
+ menu.append(self.winkb)
+ menu.append(self.mackb)
+ menu.append(self.chromekb)
+ menu.append(self.ibmkb)
+ menu.append(self.winmackb)
+
+ # grid.add(another)
+
+ GLib.timeout_add(2000, self.update_terminal)
+
+ # self.show_all()
+
+ # radiomenuitem1 = Gtk.RadioMenuItem(label="Windows")
+ # radiomenuitem1.set_active(True)
+ # menu.append(radiomenuitem1)
+ # radiomenuitem2 = Gtk.RadioMenuItem(label="Apple", group=radiomenuitem1)
+ # menu.append(radiomenuitem2)
+
+ def refresh(self,button):
+ self.refreshKB()
+
+ def refreshKB(self):
+ # Keyboard Types
+ ismac = "perl -ne 'print if /^(\s{4})((?!#).*)(# Mac\n)/' ~/.config/kinto/kinto.py | wc -l"
+ iswin = "perl -ne 'print if /^(\s{4})(# -- Default Win)/' ~/.config/kinto/kinto.py | wc -l"
+ ischrome = "perl -ne 'print if /^(\s{4})((?!#).*)(# Chromebook\n)/' ~/.config/kinto/kinto.py | wc -l"
+ iswinmac = "perl -ne 'print if /^(\s{4})(# -- Default Mac)/' ~/.config/kinto/kinto.py | wc -l"
+ isibm = "perl -ne 'print if /^(\s{4})((?!#).*)(# IBM\n)/' ~/.config/kinto/kinto.py | wc -l"
+ mac_result = int(self.queryConfig(ismac))
+ win_result = int(self.queryConfig(iswin))
+ chrome_result = int(self.queryConfig(ischrome))
+ ibm_result = int(self.queryConfig(isibm))
+ winmac_result = int(self.queryConfig(iswinmac))
+
+ countkb = 0
+
+ if mac_result:
+ self.mackb.set_active(True)
+ countkb += 1
+ if win_result:
+ self.winkb.set_active(True)
+ countkb += 1
+ if chrome_result:
+ self.chromekb.set_active(True)
+ countkb += 1
+ if winmac_result:
+ self.winmackb.set_active(True)
+ countkb += 1
+ if ibm_result:
+ ibmkb.set_active(True)
+ countkb += 1
+
+ if countkb > 1:
+ Popen(['notify-send','Kinto: Remove ' + str(countkb-1) + ' kb type(s)','-i','budgie-desktop-symbolic'])
+
+ return
+
+ def runDebug(self,button):
+ # self.InputToTerm(self.cmdbytes)
+ # self.command2 = "send \003; echo 'hello'\n"
+ command = "send \003 sudo systemctl stop xkeysnail && sudo xkeysnail ~/.config/kinto/kinto.py\n"
+ cmdbytes = str.encode(command)
+ self.InputToTerm(cmdbytes)
+
+ def openSupport(self,button):
+ Gtk.show_uri_on_window(None, "https://github.com/rbreaves/kinto#table-of-contents", Gtk.get_current_event_time())
+ return
+
+ def runAbout(self,button):
+ win = Gtk.Window()
+
+ path = os.environ['HOME']+'/.config/kinto/kinto-color.svg'
+ width = -1
+ height = 128
+ preserve_aspect_ratio = True
+
+ pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, width, height, preserve_aspect_ratio)
+ win.set_default_icon_list([pixbuf])
+
+ win.set_title("About")
+ win.set_default_size(350, 200)
+ win.set_position(Gtk.WindowPosition.CENTER)
+
+ context = win.get_style_context()
+ default_background = str(context.get_background_color(Gtk.StateType.NORMAL))
+
+ tokenValue = re.search('red=(\d.\d+), green=(\d.\d+), blue=(\d.\d+), alpha=(\d.\d+)', default_background)
+ red = float(tokenValue.group(1))
+ green = float(tokenValue.group(2))
+ blue = float(tokenValue.group(3))
+ alpha = float(tokenValue.group(4))
+
+ bgAvg = (red + green + blue)/3
+
+ if(bgAvg > 0.5):
+ theme = "light"
+ else:
+ theme = "dark"
+
+ vbox = Gtk.VBox()
+ # innervbox = Gtk.VBox()
+
+ if theme == "dark":
+ path = os.environ['HOME']+'/.config/kinto/kinto-invert.svg'
+ else:
+ path = os.environ['HOME']+'/.config/kinto/kinto-color.svg'
+ width = -1
+ height = 128
+ preserve_aspect_ratio = True
+
+ pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, width, height, preserve_aspect_ratio)
+ image = Gtk.Image()
+ image.set_from_pixbuf(pixbuf)
+
+ with open(os.environ['HOME']+'/.config/kinto/version', 'r') as file:
+ verdata = file.read().replace('\n', '')
+
+ version = Gtk.Label('Kinto v' + verdata)
+
+ credits = Gtk.Label("Author: Ben Reaves")
+ spacer = Gtk.Label(" ")
+ copy = Gtk.Label("Copyrighted 2019, 2020 - GPLv2")
+ url = Gtk.LinkButton("http://kinto.sh", label="http://kinto.sh")
+ url2 = Gtk.Label("http://kinto.sh")
+
+ vbox.add(image)
+ vbox.add(version)
+ vbox.add(spacer)
+ vbox.add(credits)
+ vbox.add(copy)
+ vbox.add(url)
+ win.add(vbox)
+
+ win.show_all()
+
+ version.set_selectable(True)
+ win.connect('delete-event', self.on_delete_event)
+
+ return
+
+ def setKB(self,button,kbtype):
+ try:
+ if kbtype == "win":
+ setkb = 's/^(\s{3})(\s{1}#)(.*# WinMac.*)|^(?!\s{4}#)(\s{3})(\s{1})(.*)( # )(Mac.*)|^(?!\s{4}#)(\s{3})(\s{1})(.*)( # )(IBM.*)|^(?!\s{4}#)(\s{3})(\s{1})(.*)( # )(Chromebook.*)|^(\s{3})(\s{1}# )(-)( Default Win)|^(\s{3})(\s{1}# )(-)(- Default Mac*)/ $3$7$6$7$8$12$11$12$13$17$16$17$18$20$21$21$22$24$26/g'
+ elif kbtype == "winmac":
+ setkb = 's/^(\s{3})(\s{1}#)(.*# WinMac.*)|^(?!\s{4}#)(\s{3})(\s{1})(.*)( # )(Mac.*)|^(?!\s{4}#)(\s{3})(\s{1})(.*)( # )(IBM.*)|^(?!\s{4}#)(\s{3})(\s{1})(.*)( # )(Chromebook.*)|^(\s{3})(\s{1}# )(-)( Default Mac.*)|^(\s{3})(\s{1}# )(-)(- Default Win)/ $3$7$6$7$8$12$11$12$13$17$16$17$18$20$21$21$22$24$26/g'
+ if os.path.isfile('/sys/module/hid_apple/parameters/swap_opt_cmd'):
+ with open('/sys/module/applespi/parameters/swap_opt_cmd', 'r') as ocval:
+ optcmd = ocval.read().replace('\n', '')
+ if optcmd == '0':
+ # print("found hid_apple")
+ self.queryConfig("echo '1' | sudo tee /sys/module/hid_apple/parameters/swap_opt_cmd;echo 'options hid_apple swap_opt_cmd=1' | sudo tee /etc/modprobe.d/hid_apple.conf;sudo update-initramfs -u -k all")
+ if os.path.isfile('/sys/module/applespi/parameters/swap_opt_cmd'):
+ with open('/sys/module/applespi/parameters/swap_opt_cmd', 'r') as ocval:
+ optcmd = ocval.read().replace('\n', '')
+ if optcmd == '0':
+ # print("found applespi")
+ self.queryConfig("echo '1' | sudo tee /sys/module/applespi/parameters/swap_opt_cmd;echo 'options applespi swap_opt_cmd=1' | sudo tee /etc/modprobe.d/applespi.conf;sudo update-initramfs -u -k all")
+ elif kbtype == "mac":
+ if os.path.isfile('/sys/module/hid_apple/parameters/swap_opt_cmd'):
+ with open('/sys/module/hid_apple/parameters/swap_opt_cmd', 'r') as ocval:
+ optcmd = ocval.read().replace('\n', '')
+ if optcmd == '1':
+ # print("found hid_apple - remove")
+ self.queryConfig("echo '0' | sudo tee /sys/module/hid_apple/parameters/swap_opt_cmd;echo 'options hid_apple swap_opt_cmd=0' | sudo tee /etc/modprobe.d/hid_apple.conf;sudo update-initramfs -u -k all")
+ if os.path.isfile('/sys/module/applespi/parameters/swap_opt_cmd'):
+ with open('/sys/module/applespi/parameters/swap_opt_cmd', 'r') as ocval:
+ optcmd = ocval.read().replace('\n', '')
+ if optcmd == '1':
+ # print("found applespi - remove")
+ self.queryConfig("echo '0' | sudo tee /sys/module/applespi/parameters/swap_opt_cmd;echo 'options applespi swap_opt_cmd=0' | sudo tee /etc/modprobe.d/applespi.conf;sudo update-initramfs -u -k all")
+ setkb = 's/^(\s{3})(\s{1}#)(.*# Mac\n|.*# Mac -)|^(?!\s{4}#)(\s{3})(\s{1})(.*)( # )(WinMac.*)|^(?!\s{4}#)(\s{3})(\s{1})(.*)( # )(IBM.*)|^(?!\s{4}#)(\s{3})(\s{1})(.*)( # )(Chromebook.*)|^(\s{3})(\s{1}# )(-)(- Default (Win|Mac.*))/ $3$7$6$7$8$12$11$12$13$17$16$17$18$20$22/g'
+ elif kbtype == "chrome":
+ setkb = 's/^(\s{3})(\s{1}#)(.*# Chromebook.*)|^(?!\s{4}#)(\s{3})(\s{1})(.*)( # )(WinMac.*)|^(?!\s{4}#)(\s{3})(\s{1})(.*)( # )(Mac.*)|^(?!\s{4}#)(\s{3})(\s{1})(.*)( # )(IBM.*)|^(\s{3})(\s{1}# )(-)(- Default (Win|Mac.*))/ $3$7$6$7$8$12$11$12$13$17$16$17$18$20$22/g'
+ elif kbtype == "ibm":
+ setkb ='s/^(\s{3})(\s{1}#)(.*# IBM.*)|^(?!\s{4}#)(\s{3})(\s{1})(.*)( # )(WinMac.*)|^(?!\s{4}#)(\s{3})(\s{1})(.*)( # )(Mac.*)|^(?!\s{4}#)(\s{3})(\s{1})(.*)( # )(Chromebook.*)|^(\s{3})(\s{1}# )(-)(- Default (Win|Mac.*))/ $3$7$6$7$8$12$11$12$13$17$16$17$18$20$22/g'
+
+ restart = ['sudo', 'systemctl','restart','xkeysnail']
+ cmds = ['perl','-pi','-e',setkb,self.kconfig]
+
+ cmdsTerm = Popen(cmds)
+ cmdsTerm.wait()
+
+ Popen(restart)
+
+ except CalledProcessError:
+ Popen(['notify-send','Kinto: Error Resetting KB Type!','-i','budgie-desktop-symbolic'])
+
+ def setTweaks(self,button):
+ win = Gtk.Window()
+
+ path = os.environ['HOME']+'/.config/kinto/kinto-color.svg'
+ width = -1
+ height = 128
+ preserve_aspect_ratio = True
+
+ pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, width, height, preserve_aspect_ratio)
+ win.set_default_icon_list([pixbuf])
+
+ win.set_title("Kinto Tweaks")
+ win.set_default_size(350, 200)
+ win.set_position(Gtk.WindowPosition.CENTER)
+
+ # Check AltGr - commented out is enabled
+ is_rightmod = "perl -ne 'print if /^(\s{4})(Key.*)(Multi-language)/' ~/.config/kinto/kinto.py | wc -l"
+ rightmod_result = int(self.queryConfig(is_rightmod))
+
+ # Sublime enabled for vscode
+ is_vsc2st3 = "perl -ne 'print if /^(\s{4}\w.*)(- Sublime)/' ~/.config/kinto/kinto.py | wc -l"
+ vsc2st3_result = int(self.queryConfig(is_vsc2st3))
+
+ # Caps2Esc enabled
+ is_caps2esc = "perl -ne 'print if /^(\s{4}{\w.*)(# Caps2Esc)/' ~/.config/kinto/kinto.py | wc -l"
+ caps2esc_result = int(self.queryConfig(is_caps2esc))
+
+ # Caps2Cmd enabled
+ is_caps2cmd = "perl -ne 'print if /^(\s{4}\w.*)(# Caps2Cmd)/' ~/.config/kinto/kinto.py | wc -l"
+ caps2cmd_result = int(self.queryConfig(is_caps2cmd))
+
+ # Enter2Cmd enabled
+ # (\s{4}{\w.*)(# Enter2Cmd)
+
+ vbox = Gtk.VBox()
+
+ self.lbl = Gtk.Label()
+ global restartsvc
+ restartsvc = False
+ self.rightmod = Gtk.CheckButton('AltGr on Right Cmd')
+ self.vsc2st3 = Gtk.CheckButton('ST3 hotkeys for VS Code')
+ self.caps2esc = Gtk.CheckButton('Capslock is Escape when tapped, Cmd when held')
+ self.caps2cmd = Gtk.CheckButton('Capslock is Cmd')
+
+ if rightmod_result == 0:
+ self.rightmod.set_active(True)
+
+ if vsc2st3_result > 0:
+ self.vsc2st3.set_active(True)
+
+ if caps2esc_result > 0:
+ self.caps2esc.set_active(True)
+ self.caps2cmd.set_sensitive(False)
+
+ if caps2cmd_result > 0:
+ self.caps2cmd.set_active(True)
+ self.caps2esc.set_sensitive(False)
+
+ self.rightmod.signal_id = self.rightmod.connect('toggled',self.setRightMod)
+ self.vsc2st3.signal_id = self.vsc2st3.connect('toggled',self.setVSC2ST3)
+ self.caps2esc.signal_id = self.caps2esc.connect('toggled',self.setCaps2Esc)
+ self.caps2cmd.signal_id = self.caps2cmd.connect('toggled',self.setCaps2Cmd)
+
+ vbox.add(self.rightmod)
+ vbox.add(self.vsc2st3)
+ vbox.add(self.caps2esc)
+ vbox.add(self.caps2cmd)
+ vbox.add(self.lbl)
+ win.add(vbox)
+
+ win.show_all()
+
+ win.connect('delete-event', self.on_delete_event)
+
+ return
+
+ __gsignals__ = {
+ "delete-event" : "override"
+ }
+
+ def on_delete_event(event, self, widget):
+ global restartsvc
+ if restartsvc == True:
+ try:
+ restartcmd = ['sudo', 'systemctl','restart','xkeysnail']
+ Popen(restartcmd)
+ restartsvc = False
+
+ except CalledProcessError:
+ Popen(['notify-send','Kinto: Error restarting Kinto after setting tweaks!','-i','budgie-desktop-symbolic'])
+
+ self.hide()
+ self.destroy()
+ return True
+
+ def queryConfig(self,query):
+ res = Popen(query, stdout=PIPE, stderr=None, shell=True)
+ res.wait()
+ return res.communicate()[0].strip().decode('UTF-8')
+
+ def setRightMod(self,button):
+ global restartsvc
+ try:
+ if self.winkb.get_active() or self.winmackb.get_active():
+ # print('winkb true')
+ setkb = 's/^(\s{4})((# )(.*)(# )(WinMac - Multi-language.*)|(K)(.*)(# )(WinMac - Multi-language.*))/ $4$5$6$9$7$8$9$10/g'
+ if self.mackb.get_active():
+ # print('mackb true')
+ setkb = 's/^(\s{4})((# )(.*)(# )(Mac - Multi-language.*)|(K)(.*)(# )(Mac - Multi-language.*))/ $4$5$6$9$7$8$9$10/g'
+ if self.chromekb.get_active():
+ # print('chromekb true')
+ setkb = 's/^(\s{4})((# )(.*)(# )(Chromebook - Multi-language.*)|(K)(.*)(# )(Chromebook - Multi-language.*))/ $4$5$6$9$7$8$9$10/g'
+ if self.ibmkb.get_active():
+ # print('ibmkb true')
+ setkb = 's/^(\s{4})((# )(.*)(# )(IBM - Multi-language.*)|(K)(.*)(# )(IBM - Multi-language.*))/ $4$5$6$9$7$8$9$10/g'
+
+ cmds = ['perl','-pi','-e',setkb,self.kconfig]
+
+ cmdsTerm = Popen(cmds)
+
+ restartsvc = True
+
+ except CalledProcessError:
+ Popen(['notify-send','Kinto: Error Resetting AltGr!','-i','budgie-desktop-symbolic'])
+
+ return
+
+ def setVSC2ST3(self,button):
+ global restartsvc
+
+ try:
+ if self.chromekb.get_active() or self.ibmkb.get_active():
+ setkb = 's/^(\s{4})(\w.*)(# )(Chromebook/IBM - Sublime)|^(\s{4})(# )(\w.*)(# Chromebook/IBM - Sublime)/$5$7$8$1$3$2$3$4/g'
+ else:
+ setkb = 's/^(\s{4})(\w.*)(# )(Default - Sublime)|^(\s{4})(# )(\w.*)(# Default - Sublime)/$5$7$8$1$3$2$3$4/g'
+
+ cmds = ['perl','-pi','-e',setkb,self.kconfig]
+
+ cmdsTerm = Popen(cmds)
+
+ restartsvc = True
+
+ except CalledProcessError:
+ Popen(['notify-send','Kinto: Error Resetting SublimeText remaps for VSCode!','-i','budgie-desktop-symbolic'])
+ return
+
+ def setCaps2Esc(self,button):
+
+ global restartsvc
+ try:
+ if self.winkb.get_active() or self.winmackb.get_active() or self.ibmkb.get_active() or self.mackb.get_active():
+ setkb = 's/^(\s{4})((# )(\{\w.*)(# Caps2Esc\n)|(\{\w.*)(# )(Caps2Esc - Chrome.*)|(\{.*)(# )(Caps2Esc\n|Placeholder)|(\w.*)(# )(Caps2Cmd.*)|(# )(\{.*)(# )(Placeholder))/ $4$5$7$6$7$8$10$9$10$11$13$12$13$14$16$17$18/g'
+ if self.chromekb.get_active():
+ setkb = 's/^(\s{4})((# )(\{\w.*)(# Caps2Esc - Chrome.*)|(\{\w.*)(# )(Caps2Esc\n)|(\{.*)(# )(Caps2Esc - Chrome.*|Placeholder)|(\w.*)(# )(Caps2Cmd.*)|(# )(\{.*)(# )(Placeholder))/ $4$5$7$6$7$8$10$9$10$11$13$12$13$14$16$17$18/g'
+
+ cmds = ['perl','-pi','-e',setkb,self.kconfig]
+
+ if self.caps2esc.get_active():
+ self.caps2cmd.set_sensitive(False)
+ else:
+ self.caps2cmd.set_sensitive(True)
+
+ cmdsTerm = Popen(cmds)
+
+ restartsvc = True
+
+ except CalledProcessError:
+ Popen(['notify-send','Kinto: Error resetting caps2esc!','-i','budgie-desktop-symbolic'])
+
+ return
+
+ def setCaps2Cmd(self,button):
+
+ global restartsvc
+
+ try:
+ if self.winkb.get_active() or self.winmackb.get_active() or self.ibmkb.get_active() or self.mackb.get_active():
+ setkb = 's/^(\s{4})((\w.*)(# )(Caps2Cmd\n)|(\w.*)(# )(Caps2Cmd - Chrome.*)|(# )(\w.*)(# )(Caps2Cmd\n)|(\{\w.*)(# )(Caps2Esc.*)|(# )(\{.*)(# )(Placeholder))/ $4$3$4$5$7$6$7$8$10$11$12$14$13$14$15$17$18$19/g'
+ if self.chromekb.get_active():
+ setkb = 's/^(\s{4})((\w.*)(# )(Caps2Cmd - Chrome.*)|(\w.*)(# )(Caps2Cmd\n)|(# )(\w.*)(# )(Caps2Cmd - Chrome.*)|(\{\w.*)(# )(Caps2Esc.*)|(# )(\{.*)(# )(Placeholder))/ $4$3$4$5$7$6$7$8$10$11$12$14$13$14$15$17$18$19/g'
+
+ cmds = ['perl','-pi','-e',setkb,self.kconfig]
+
+ if self.caps2cmd.get_active():
+ self.caps2esc.set_sensitive(False)
+ else:
+ self.caps2esc.set_sensitive(True)
+
+ cmdsTerm = Popen(cmds)
+
+ restartsvc = True
+
+ except CalledProcessError:
+ Popen(['notify-send','Kinto: Error resetting caps2cmd!','-i','budgie-desktop-symbolic'])
+
+ return
+
+ def runRestart(self,button):
+ try:
+ stop = Popen(['sudo', 'systemctl','stop','xkeysnail'])
+ stop.wait()
+ time.sleep(1)
+ res = Popen(['pgrep','xkeysnail'])
+ res.wait()
+
+ if res.returncode == 0:
+ pkillxkey = Popen(['sudo', 'pkill','-f','bin/xkeysnail'])
+ pkillxkey.wait()
+ Popen(['sudo', 'systemctl','start','xkeysnail'])
+ command = "send \003 journalctl -f --unit=xkeysnail.service -b\n"
+ cmdbytes = str.encode(command)
+ self.InputToTerm(cmdbytes)
+ except:
+ Popen(['notify-send','Kinto: Error restarting Kinto!','-i','budgie-desktop-symbolic'])
+
+ def setEnable(self,button,enableKinto):
+ try:
+ if enableKinto:
+ res = Popen(['pgrep','xkeysnail'])
+ res.wait()
+ print(res.returncode)
+
+ if res.returncode == 0:
+ # Popen(['notify-send','Kinto: Err in debug mode?','-i','budgie-desktop-symbolic'])
+ pkillxkey = Popen(['sudo', 'pkill','-f','bin/xkeysnail'])
+ pkillxkey.wait()
+
+ Popen(['sudo', 'systemctl','restart','xkeysnail'])
+ self.menuitem_enable.disconnect(self.menuitem_enable.signal_id)
+ self.menuitem_enable.set_active(True)
+ self.menuitem_enable.signal_id = self.menuitem_enable.connect('activate',self.setEnable,False)
+ command = "send \003 journalctl -f --unit=xkeysnail.service -b\n"
+ cmdbytes = str.encode(command)
+ self.InputToTerm(cmdbytes)
+ else:
+ Popen(['sudo', 'systemctl','stop','xkeysnail'])
+ self.menuitem_enable.disconnect(self.menuitem_enable.signal_id)
+ self.menuitem_enable.set_active(False)
+ self.menuitem_enable.signal_id = self.menuitem_enable.connect('activate',self.setEnable,True)
+ except CalledProcessError:
+ Popen(['notify-send','Kinto: Error enabling!','-i','budgie-desktop-symbolic'])
+
+ def setAutostart(self,button,autostart):
+ try:
+ if autostart == False:
+ Popen(['perl','-pi','-e','s/autostart = true/autostart = false/g',os.environ['HOME']+'/.config/kinto/kinto.py'])
+ self.menuitem_auto.set_active(False)
+ self.menuitem_auto.disconnect(self.menuitem_auto.signal_id)
+ self.menuitem_auto.signal_id = self.menuitem_auto.connect('activate',self.setAutostart,True)
+ else:
+ Popen(['perl','-pi','-e','s/autostart = false/autostart = true/g',os.environ['HOME']+'/.config/kinto/kinto.py'])
+ self.menuitem_auto.set_active(True)
+ self.menuitem_auto.disconnect(self.menuitem_auto.signal_id)
+ self.menuitem_auto.signal_id = self.menuitem_auto.connect('activate',self.setAutostart,False)
+
+ except CalledProcessError:
+ Popen(['notify-send','Kinto: Error setting autostart!','-i','budgie-desktop-symbolic'])
+
+ def setConfig(self,button):
+ try:
+ if os.path.exists('/opt/sublime_text/sublime_text'):
+ Popen(['/opt/sublime_text/sublime_text',os.environ['HOME']+'/.config/kinto/kinto.py'])
+ elif which(gedit) is not None:
+ Popen(['gedit',os.environ['HOME']+'/.config/kinto/kinto.py'])
+ elif which(mousepad) is not None:
+ Popen(['mousepad',os.environ['HOME']+'/.config/kinto/kinto.py'])
+
+ except CalledProcessError: # Notify user about error on running restart commands.
+ Popen(['notify-send','Kinto: Error could not open config file!','-i','budgie-desktop-symbolic'])
+
+ def setService(self,button):
+ try:
+ if os.path.exists('/opt/sublime_text/sublime_text'):
+ Popen(['/opt/sublime_text/sublime_text','/lib/systemd/system/xkeysnail.service'])
+ elif which(gedit) is not None:
+ Popen(['gedit','/lib/systemd/system/xkeysnail.service'])
+ elif which(mousepad) is not None:
+ Popen(['mousepad','/lib/systemd/system/xkeysnail.service'])
+
+ except CalledProcessError: # Notify user about error on running restart commands.
+ Popen(['notify-send','Kinto: Error could not open config file!','-i','budgie-desktop-symbolic'])
+
+ def setSysKB(self,button):
+ if self.ostype == "XFCE":
+ Popen(['xfce4-keyboard-settings'])
+ else:
+ Popen(['gnome-control-center','keyboard'])
+
+ def setRegion(self,button):
+ if self.ostype == "XFCE":
+ Popen(['gnome-language-selector'])
+ else:
+ Popen(['gnome-control-center','region'])
+
+ def remove_control_characters(self,s):
+ return "".join(ch for ch in s if unicodedata.category(ch)[0]!="C")
+
+ def non_block_read(self):
+ ''' even in a thread, a normal read with block until the buffer is full '''
+ output = self.kinto_status.stdout
+ # with open('goodlines.txt') as f:
+ # mylist = list(f)
+ # output = '\n'.join(self.kinto_status.stdout.splitlines()[-1:])
+ # '\n'.join(stderr.splitlines()[-N:])
+ # .splitlines()[-1:]
+ fd = output.fileno()
+ fl = fcntl.fcntl(fd, fcntl.F_GETFL)
+ fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
+ op = output.read()
+ if op == None:
+ return ''
+
+ # print(output.read())
+
+ # the_encoding = chardet.detect(output)['encoding']
+ # print(str(the_encoding) + " hello")
+ # full = self.status.get_text() + op.decode('utf-8')
+ # newstr = re.sub('[^A-Za-z0-9]+', '', op.decode('utf-8'))
+ # print(newstr)
+ status = op.decode('utf-8').rstrip()
+ if "inactive" in status or "failed" in status or "deactivating" in status:
+ if "journalctl" in self.command:
+ stats = "inactive"
+ else:
+ stats = "Debug Mode"
+ # elif "failed" in op.decode('utf-8').rstrip():
+ # stats = "failed"
+ else:
+ stats = "active"
+ # op.decode('utf-8').rstrip()
+ return stats
+
+ def remove_tags(self,raw_html):
+ cleanr = re.compile('<.*?>')
+ cleantext = re.sub(cleanr, '', raw_html).strip()
+ return cleantext
+
+ def update_terminal(self):
+ # subproc = self.sub_proc
+ # print(self.another.get_text())
+ # self.label.set_text(self.non_block_read())
+ status = self.non_block_read()
+ # print (self.label.get_text().strip() + ' ' + self.remove_tags(status))
+ if self.label.get_text().strip() != self.remove_tags(status):
+ self.label.set_markup(" " + status + " ")
+ if self.remove_tags(status) == 'active':
+ self.menuitem_enable.disconnect(self.menuitem_enable.signal_id)
+ self.menuitem_enable.set_active(True)
+ self.menuitem_enable.signal_id = self.menuitem_enable.connect('activate',self.setEnable,False)
+ else:
+ self.menuitem_enable.disconnect(self.menuitem_enable.signal_id)
+ self.menuitem_enable.set_active(False)
+ self.menuitem_enable.signal_id = self.menuitem_enable.connect('activate',self.setEnable,True)
+
+ return self.kinto_status.poll() is None
+
+ # def update_terminal(self):
+ # # subproc = self.sub_proc
+ # # print(self.another.get_text())
+ # self.label.set_text(self.label.get_text() + self.non_block_read())
+ # return self.sub_proc.poll() is None
+
+ def InputToTerm(self,cmd):
+ terminal.feed_child_binary(cmd)
+ print(Vte.get_minor_version())
+
+ # def on_menu_auto(self, widget):
+ # print("add file open dialog")
+
+ # def on_menu_enable(self, widget):
+ # print("add file open dialog")
+
+ def on_menu_quit(self, widget):
+ Gtk.main_quit()
+
+
+win = MyWindow()
+win.connect("delete-event", Gtk.main_quit)
+win.show_all()
+
+Gtk.main()
\ No newline at end of file
diff --git a/xkeysnail-config/gui/kinto.desktop b/xkeysnail-config/gui/kinto.desktop
new file mode 100644
index 0000000..0fb95cf
--- /dev/null
+++ b/xkeysnail-config/gui/kinto.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+# /.local/share/applications
+Name=Kinto.sh
+GenericName=Kinto.sh
+Categories=Utility;
+Type=Application
+Exec={path}/kinto-gui.py
+Icon={home}/.config/kinto/kinto-color-48.svg
+# Icon=/usr/share/icons/Pocillo/kinto-color.svg
+Terminal=false
+NoDisplay=false
diff --git a/xkeysnail-config/gui/term.py b/xkeysnail-config/gui/term.py
new file mode 100755
index 0000000..a707037
--- /dev/null
+++ b/xkeysnail-config/gui/term.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python3
+import gi
+# import textwrap
+gi.require_version('Gtk', '3.0')
+
+from gi.repository import Gtk
+from gi.repository import GObject
+
+import os
+from subprocess import Popen, PIPE
+import fcntl
+
+wnd = Gtk.Window()
+wnd.set_default_size(400, 400)
+wnd.connect("destroy", Gtk.main_quit)
+sw = Gtk.ScrolledWindow()
+label = Gtk.Label()
+label.set_alignment(0, 0)
+label.set_selectable(True)
+label.set_line_wrap(True)
+label.set_max_width_chars(150)
+sw.add_with_viewport(label)
+wnd.add(sw)
+wnd.show_all()
+sub_proc = Popen("journalctl -f --unit=xkeysnail.service -b", stdout=PIPE, shell=True)
+# sub_proc2 = Popen('fold', stdin=sub_proc.stdout, stdout=PIPE)
+# sub_proc2.communicate()
+sub_outp = ""
+
+
+def non_block_read(output):
+ ''' even in a thread, a normal read with block until the buffer is full '''
+ fd = output.fileno()
+ fl = fcntl.fcntl(fd, fcntl.F_GETFL)
+ fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
+ op = output.read()
+ if op == None:
+ return ''
+ return op.decode('utf-8')
+
+# def wrap(s, w):
+# return textwrap.fill(s, w)
+# def wrap(s, w):
+# return [s[i:i + w] for i in range(0, len(s), w)]
+
+def update_terminal():
+ # wrapper = textwrap.TextWrapper(width=50)
+ # word_list = wrapper.wrap(text=sub_proc.stdout)
+ label.set_text(label.get_text() + non_block_read(sub_proc.stdout))
+ return sub_proc.poll() is None
+
+GObject.timeout_add(100, update_terminal)
+Gtk.main()
\ No newline at end of file
diff --git a/xkeysnail-config/gui/vte.py b/xkeysnail-config/gui/vte.py
new file mode 100755
index 0000000..baffd32
--- /dev/null
+++ b/xkeysnail-config/gui/vte.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+
+from gi.repository import Gtk,GObject, Vte
+from gi.repository import GLib
+import os
+
+class TheWindow(Gtk.Window):
+
+ def __init__(self):
+ Gtk.Window.__init__(self, title="inherited cell renderer")
+ self.set_default_size(600, 300)
+ global terminal
+ terminal = Vte.Terminal()
+ terminal.spawn_sync(
+ Vte.PtyFlags.DEFAULT,
+ os.environ['HOME'],
+ ["/bin/bash"],
+ [],
+ GLib.SpawnFlags.DO_NOT_REAP_CHILD,
+ None,
+ None,
+ )
+
+ self.button = Gtk.Button("Do The Command")
+ self.button2 = Gtk.Button("End Command")
+ self.command = "journalctl -f --unit=xkeysnail.service -b\n"
+ self.command2 = "send \003; echo 'hello'\n"
+ # expect -c "send \003;"
+ self.cmdbytes = str.encode(self.command)
+ self.cmdbytes2 = str.encode(self.command2)
+ command = Gtk.Label("The command: "+self.command)
+ self.button.connect("clicked", self.InputToTerm, self.cmdbytes)
+ self.button2.connect("clicked", self.InputToTerm, self.cmdbytes2)
+
+ box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
+ box.pack_start(self.button, False, True, 0)
+ box.pack_start(self.button2, False, True, 0)
+ box.pack_start(command, False, True, 1)
+ scroller = Gtk.ScrolledWindow()
+ scroller.set_hexpand(True)
+ scroller.set_vexpand(True)
+ scroller.add(terminal)
+ box.pack_start(scroller, False, True, 2)
+ self.add(box)
+
+ def InputToTerm(self, clicker, cmd):
+ terminal.feed_child_binary(cmd)
+ print(Vte.get_minor_version())
+
+
+win = TheWindow()
+win.connect("delete-event", Gtk.main_quit)
+win.show_all()
+Gtk.main()
\ No newline at end of file
diff --git a/xkeysnail-config/kinto.py b/xkeysnail-config/kinto.py
index b575a24..6ce5813 100644
--- a/xkeysnail-config/kinto.py
+++ b/xkeysnail-config/kinto.py
@@ -7,7 +7,7 @@ from xkeysnail.transform import *
# Use the following for testing terminal keymaps
# terminals = [ "", ... ]
# xbindkeys -mk
-terminals = ["gnome-terminal","konsole","io.elementary.terminal","terminator","sakura","guake","tilda","xterm","eterm","kitty","alacritty","mate-terminal","tilix","xfce4-terminal"]
+terminals = ["kinto-gui.py","gnome-terminal","konsole","io.elementary.terminal","terminator","sakura","guake","tilda","xterm","eterm","kitty","alacritty","mate-terminal","tilix","xfce4-terminal"]
terminals = [term.casefold() for term in terminals]
termStr = "|".join(str(x) for x in terminals)
diff --git a/xkeysnail-config/limitedadmins b/xkeysnail-config/limitedadmins
index b140516..1a3e933 100644
--- a/xkeysnail-config/limitedadmins
+++ b/xkeysnail-config/limitedadmins
@@ -5,4 +5,6 @@
%{username} ALL=NOPASSWD: {systemctl} status xkeysnail
%{username} ALL=(root) NOPASSWD: /usr/local/bin/logoff.sh
%{username} ALL=NOPASSWD: {pkill} -f logoff
+%{username} ALL=NOPASSWD: {pkill} -f bin/xkeysnail
+%{username} ALL=NOPASSWD: {xkeysnail} /home/{username}/.config/kinto/kinto.py
%{username} ALL=NOPASSWD: {systemctl} is-active --quiet xkeysnail
diff --git a/xkeysnail-config/trayapps/appindicator/kintotray.py b/xkeysnail-config/trayapps/appindicator/kintotray.py
index 17e60ac..a1e4603 100755
--- a/xkeysnail-config/trayapps/appindicator/kintotray.py
+++ b/xkeysnail-config/trayapps/appindicator/kintotray.py
@@ -6,16 +6,32 @@ gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
gi.require_version('Notify', '0.7')
-import signal,subprocess,time,os
+import signal,time,os,fcntl,datetime,re
+from subprocess import Popen, PIPE, CalledProcessError
from shutil import which
-from gi.repository import Gtk
+from gi.repository import Gtk,GLib,GdkPixbuf
from gi.repository import AppIndicator3 as appindicator
from gi.repository import Notify as notify
+import signal
+
+def kill_child():
+ if child_pid is None:
+ pass
+ else:
+ os.kill(child_pid, signal.SIGTERM)
+
+import atexit
+atexit.register(kill_child)
+
APPINDICATOR_ID = 'Kinto'
class Indicator():
+ global child_pid
+ kinto_status = Popen("while :; do clear; systemctl is-active xkeysnail; sleep 2s; done", stdout=PIPE, shell=True)
+ child_pid = kinto_status.pid
+
homedir = os.path.expanduser("~")
kconfig = homedir+"/.config/kinto/kinto.py"
ostype = os.environ.get('XDG_CURRENT_DESKTOP')
@@ -26,9 +42,9 @@ class Indicator():
autostart_bool = False
menu = Gtk.Menu()
menukb = Gtk.Menu()
- tweaks = Gtk.MenuItem('Tweaks')
checkbox_autostart = Gtk.CheckMenuItem('Autostart')
checkbox_enable = Gtk.CheckMenuItem('Kinto Enabled')
+ restart = Gtk.MenuItem('Restart')
keyboards = Gtk.MenuItem('Keyboard Types')
keyboards.set_submenu(menukb)
winkb = Gtk.RadioMenuItem(label='Windows')
@@ -36,24 +52,48 @@ class Indicator():
chromekb = Gtk.RadioMenuItem(label='Chromebook',group=winkb)
ibmkb = Gtk.RadioMenuItem(label='IBM (No Super/Win key)',group=winkb)
winmackb = Gtk.RadioMenuItem(label='Windows & Apple*',group=winkb)
+ edit = Gtk.MenuItem('Customize')
+ edit_submenu = Gtk.Menu()
+ edit.set_submenu(edit_submenu)
+ tweaks = Gtk.MenuItem('Tweaks')
rightmod = Gtk.CheckButton('AltGr on Right Cmd')
vsc2st3 = Gtk.CheckButton('ST3 hotkeys for VS Code')
caps2esc = Gtk.CheckButton('Capslock is Escape when tapped, Cmd when held')
caps2cmd = Gtk.CheckButton('Capslock is Cmd')
- button_config = Gtk.MenuItem('Edit Config')
+ button_config = Gtk.MenuItem('Kinto Config (shortcuts)')
+ service = Gtk.MenuItem('Kinto Service')
# Keyboard type set below
button_syskb = Gtk.MenuItem('System Shortcuts')
button_region = Gtk.MenuItem('Change Language')
- button_support = Gtk.MenuItem('Support')
+ helpm = Gtk.MenuItem('Help')
+ help_submenu = Gtk.Menu()
+ helpm.set_submenu(help_submenu)
+ debug = Gtk.MenuItem('Debug')
+ support = Gtk.MenuItem("Support")
+ about = Gtk.MenuItem('About')
global restartsvc
+ restartsvc = False
+ unixts = int(time.time())
+ last_status = ""
def __init__(self):
- self.indicator = appindicator.Indicator.new(APPINDICATOR_ID, self.homedir+'/.config/kinto/kinto-invert.svg', appindicator.IndicatorCategory.SYSTEM_SERVICES)
+ res = Popen(['sudo', 'systemctl','is-active','--quiet','xkeysnail'])
+ res.wait()
+
+ if res.returncode == 0:
+ self.last_status = 'active'
+ self.indicator = appindicator.Indicator.new(APPINDICATOR_ID, os.environ['HOME']+'/.config/kinto/kinto-invert.svg', appindicator.IndicatorCategory.SYSTEM_SERVICES)
+ else:
+ self.last_status = 'inactive'
+ self.indicator = appindicator.Indicator.new(APPINDICATOR_ID, os.environ['HOME']+'/.config/kinto/kinto.svg', appindicator.IndicatorCategory.SYSTEM_SERVICES)
+
self.indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
- self.indicator.set_menu(self.build_menu())
+ self.indicator.set_menu(self.build_menu(res))
notify.init(APPINDICATOR_ID)
- def build_menu(self):
+ GLib.timeout_add(2000, self.update_terminal)
+
+ def build_menu(self,res):
with open(self.kconfig) as configfile:
autostart_line = configfile.read().split('\n')[1]
@@ -63,7 +103,7 @@ class Indicator():
autostart_bool = True
if autostart_bool:
- subprocess.Popen(['sudo', 'systemctl','restart','xkeysnail'])
+ # Popen(['sudo', 'systemctl','restart','xkeysnail'])
self.checkbox_autostart.set_active(True)
self.chkautostart_id = self.checkbox_autostart.connect('activate',self.setAutostart,False)
else:
@@ -73,22 +113,104 @@ class Indicator():
# Kinto Enable
- res = subprocess.Popen(['sudo', 'systemctl','is-active','--quiet','xkeysnail'])
- res.wait()
- time.sleep(5)
+ # res = Popen(['sudo', 'systemctl','is-active','--quiet','xkeysnail'])
+ # res.wait()
+ # time.sleep(5)
- self.checkbox_enable.set_label("Kinto Enabled")
+ # self.checkbox_enable.set_label("Kinto Enabled")
+ # self.checkbox_enable.set_active(True)
+ # self.enable_id = self.checkbox_enable.connect('activate',self.setEnable,False)
if res.returncode == 0:
self.checkbox_enable.set_active(True)
- self.indicator.set_icon(self.homedir+'/.config/kinto/kinto-invert.svg')
+ # self.indicator.set_icon(os.environ['HOME']+'/.config/kinto/kinto-invert.svg')
self.enable_id = self.checkbox_enable.connect('activate',self.setEnable,False)
else:
self.checkbox_enable.set_active(False)
- self.indicator.set_icon(self.homedir+'/.config/kinto/kinto-color.svg')
+ # self.indicator.set_icon(os.environ['HOME']+'/.config/kinto/kinto-color.svg')
self.enable_id = self.checkbox_enable.connect('activate',self.setEnable,True)
self.menu.append(self.checkbox_enable)
+ self.restart.connect('activate',self.runRestart)
+ self.menu.append(self.restart)
+
+ self.refreshKB()
+
+ self.mackb.signal_id = self.mackb.connect('activate',self.setKB,"mac")
+ self.winkb.signal_id = self.winkb.connect('activate',self.setKB,"win")
+ self.chromekb.signal_id = self.chromekb.connect('activate',self.setKB,"chrome")
+ self.ibmkb.signal_id = self.ibmkb.connect('activate',self.setKB,"ibm")
+ self.winmackb.signal_id = self.winmackb.connect('activate',self.setKB,"winmac")
+
+ self.menukb.append(self.winkb)
+ self.menukb.append(self.mackb)
+ self.menukb.append(self.chromekb)
+ self.menukb.append(self.ibmkb)
+ self.menukb.append(self.winmackb)
+ self.menu.append(self.keyboards)
+
+ self.tweaks.connect('activate',self.setTweaks)
+ self.edit_submenu.append(self.tweaks)
+ self.button_config.connect('activate',self.setConfig)
+ self.edit_submenu.append(self.button_config)
+ self.service.connect('activate',self.setService)
+ self.edit_submenu.append(self.service)
+ # Set System Keyboard Shortcuts
+ self.button_syskb.connect('activate',self.setSysKB)
+ self.edit_submenu.append(self.button_syskb)
+ # Set Language
+ self.button_region.connect('activate',self.setRegion)
+ self.edit_submenu.append(self.button_region)
+ self.menu.append(self.edit)
+
+ self.debug.connect('activate',self.runDebug)
+ self.help_submenu.append(self.debug)
+ self.support.connect('activate',self.openSupport)
+ self.help_submenu.append(self.support)
+ self.about.connect('activate',self.runAbout)
+ self.help_submenu.append(self.about)
+ self.menu.append(self.helpm)
+
+ self.keyboards.connect('activate',self.refresh)
+
+ # self.debug.connect('activate',self.runDebug)
+ # self.menu.append(self.debug)
+
+ # self.tweaks.connect('activate',self.setTweaks)
+ # self.menu.append(self.tweaks)
+
+ # Edit Config
+ # self.button_config.connect('activate',self.setConfig)
+ # self.menu.append(self.button_config)
+
+ # # Set System Keyboard Shortcuts
+ # self.button_syskb.connect('activate',self.setSysKB)
+ # self.menu.append(self.button_syskb)
+
+ # # Set Language
+ # self.button_region.connect('activate',self.setRegion)
+ # self.menu.append(self.button_region)
+
+ item_quit = Gtk.MenuItem('Close')
+ item_quit.connect('activate', quit)
+ self.menu.append(item_quit)
+ self.menu.show_all()
+
+ return self.menu
+
+ # def refresh(self, widget, event):
+ # print('refresh!!!')
+ # if event.button != 1:
+ # return False #only intercept left mouse button
+ # md = gtk.MessageDialog(self, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO, gtk.BUTTONS_CLOSE, "herp derp, I only needed one click")
+ # md.run()
+ # md.destroy()
+ # return True
+
+ def refresh(self,button):
+ self.refreshKB()
+
+ def refreshKB(self):
# Keyboard Types
ismac = "perl -ne 'print if /^(\s{4})((?!#).*)(# Mac\n)/' ~/.config/kinto/kinto.py | wc -l"
iswin = "perl -ne 'print if /^(\s{4})(# -- Default Win)/' ~/.config/kinto/kinto.py | wc -l"
@@ -116,50 +238,145 @@ class Indicator():
self.winmackb.set_active(True)
countkb += 1
if ibm_result:
- self.ibmkb.set_active(True)
+ ibmkb.set_active(True)
countkb += 1
if countkb > 1:
- subprocess.Popen(['notify-send','Kinto: Remove ' + str(countkb-1) + ' kb type(s)','-i','budgie-desktop-symbolic'])
+ Popen(['notify-send','Kinto: Remove ' + str(countkb-1) + ' kb type(s)','-i','budgie-desktop-symbolic'])
- self.mackb.signal_id = self.mackb.connect('activate',self.setKB,"mac")
- self.winkb.signal_id = self.winkb.connect('activate',self.setKB,"win")
- self.chromekb.signal_id = self.chromekb.connect('activate',self.setKB,"chrome")
- self.ibmkb.signal_id = self.ibmkb.connect('activate',self.setKB,"ibm")
- self.winmackb.signal_id = self.winmackb.connect('activate',self.setKB,"winmac")
+ return
- self.menukb.append(self.winkb)
- self.menukb.append(self.mackb)
- self.menukb.append(self.chromekb)
- self.menukb.append(self.ibmkb)
- self.menukb.append(self.winmackb)
- self.menu.append(self.keyboards)
+ def non_block_read(self):
+ ''' even in a thread, a normal read with block until the buffer is full '''
+ output = self.kinto_status.stdout
+ # with open('goodlines.txt') as f:
+ # mylist = list(f)
+ # output = '\n'.join(self.kinto_status.stdout.splitlines()[-1:])
+ # '\n'.join(stderr.splitlines()[-N:])
+ # .splitlines()[-1:]
+ fd = output.fileno()
+ fl = fcntl.fcntl(fd, fcntl.F_GETFL)
+ fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
+ op = output.read()
+ if op == None:
+ return ''
+ status = op.decode('utf-8').rstrip()
+ if "inactive" in status or "failed" in status or "deactivating" in status or "activating" in status:
+ stats = "inactive"
+ else:
+ stats = "active"
+ return stats
- self.tweaks.connect('activate',self.setTweaks)
+ def update_terminal(self):
+ status = self.non_block_read().strip()
+ nowts = int(time.time())
+ if (nowts - self.unixts) > 5 and (status=='active' and self.indicator.get_icon() != os.environ['HOME']+'/.config/kinto/kinto-invert.svg'):
+ self.checkbox_enable.disconnect(self.enable_id)
+ self.checkbox_enable.set_active(True)
+ self.enable_id = self.checkbox_enable.connect('activate',self.setEnable,False)
+ self.indicator.set_icon(os.environ['HOME']+'/.config/kinto/kinto-invert.svg')
+ elif (nowts - self.unixts) > 5 and (status == 'inactive' and self.indicator.get_icon() != os.environ['HOME']+'/.config/kinto/kinto.svg'):
+ self.checkbox_enable.disconnect(self.enable_id)
+ self.checkbox_enable.set_active(False)
+ self.enable_id = self.checkbox_enable.connect('activate',self.setEnable,True)
+ self.indicator.set_icon(os.environ['HOME']+'/.config/kinto/kinto.svg')
- self.menu.append(self.tweaks)
+ # print('stats: ' + status + ' last: ' + self.last_status)
+ # if status != self.last_status and status == 'active':
+ # # print('inside')
+ # self.refreshKB()
- # Edit Config
- self.button_config.connect('activate',self.setConfig)
- self.menu.append(self.button_config)
+ self.last_status = status
- # Set System Keyboard Shortcuts
- self.button_syskb.connect('activate',self.setSysKB)
- self.menu.append(self.button_syskb)
+ return self.kinto_status.poll() is None
- # Set Language
- self.button_region.connect('activate',self.setRegion)
- self.menu.append(self.button_region)
+ def openSupport(self,button):
+ Gtk.show_uri_on_window(None, "https://github.com/rbreaves/kinto#table-of-contents", Gtk.get_current_event_time())
+ return
- item_quit = Gtk.MenuItem('Close')
- item_quit.connect('activate', quit)
- self.menu.append(item_quit)
- self.menu.show_all()
+ def runAbout(self,button):
+ win = Gtk.Window()
- return self.menu
+ path = os.environ['HOME']+'/.config/kinto/kinto-color.svg'
+ width = -1
+ height = 128
+ preserve_aspect_ratio = True
+
+ pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, width, height, preserve_aspect_ratio)
+ win.set_default_icon_list([pixbuf])
+
+ win.set_title("About")
+ win.set_default_size(350, 200)
+ win.set_position(Gtk.WindowPosition.CENTER)
+
+ context = win.get_style_context()
+ default_background = str(context.get_background_color(Gtk.StateType.NORMAL))
+
+ tokenValue = re.search('red=(\d.\d+), green=(\d.\d+), blue=(\d.\d+), alpha=(\d.\d+)', default_background)
+ red = float(tokenValue.group(1))
+ green = float(tokenValue.group(2))
+ blue = float(tokenValue.group(3))
+ alpha = float(tokenValue.group(4))
+
+ bgAvg = (red + green + blue)/3
+
+ if(bgAvg > 0.5):
+ theme = "light"
+ else:
+ theme = "dark"
+
+ vbox = Gtk.VBox()
+ # innervbox = Gtk.VBox()
+
+ if theme == "dark":
+ path = os.environ['HOME']+'/.config/kinto/kinto-invert.svg'
+ else:
+ path = os.environ['HOME']+'/.config/kinto/kinto-color.svg'
+ width = -1
+ height = 128
+ preserve_aspect_ratio = True
+
+ pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, width, height, preserve_aspect_ratio)
+ image = Gtk.Image()
+ image.set_from_pixbuf(pixbuf)
+
+ with open('version', 'r') as file:
+ verdata = file.read().replace('\n', '')
+
+ version = Gtk.Label('Kinto v' + verdata)
+
+ credits = Gtk.Label("Author: Ben Reaves")
+ spacer = Gtk.Label(" ")
+ copy = Gtk.Label("Copyrighted 2019, 2020 - GPLv2")
+ url = Gtk.LinkButton("http://kinto.sh", label="http://kinto.sh")
+ url2 = Gtk.Label("http://kinto.sh")
+
+ vbox.add(image)
+ vbox.add(version)
+ vbox.add(spacer)
+ vbox.add(credits)
+ vbox.add(copy)
+ vbox.add(url)
+ win.add(vbox)
+
+ win.show_all()
+
+ version.set_selectable(True)
+ win.connect('delete-event', self.on_delete_event)
+
+ return
def setTweaks(self,button):
win = Gtk.Window()
+
+ path = os.environ['HOME']+'/.config/kinto/kinto-color.svg'
+ width = -1
+ height = 128
+ preserve_aspect_ratio = True
+
+ pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(path, width, height, preserve_aspect_ratio)
+ win.set_default_icon_list([pixbuf])
+
win.set_title("Kinto Tweaks")
win.set_default_size(350, 200)
win.set_position(Gtk.WindowPosition.CENTER)
@@ -234,11 +451,11 @@ class Indicator():
if restartsvc == True:
try:
restartcmd = ['sudo', 'systemctl','restart','xkeysnail']
- subprocess.Popen(restartcmd)
+ Popen(restartcmd)
restartsvc = False
- except subprocess.CalledProcessError:
- subprocess.Popen(['notify-send','Kinto: Error restarting Kinto after setting tweaks!','-i','budgie-desktop-symbolic'])
+ except CalledProcessError:
+ Popen(['notify-send','Kinto: Error restarting Kinto after setting tweaks!','-i','budgie-desktop-symbolic'])
self.hide()
self.destroy()
@@ -262,12 +479,12 @@ class Indicator():
cmds = ['perl','-pi','-e',setkb,self.kconfig]
- cmdsTerm = subprocess.Popen(cmds)
+ cmdsTerm = Popen(cmds)
restartsvc = True
- except subprocess.CalledProcessError:
- subprocess.Popen(['notify-send','Kinto: Error Resetting AltGr!','-i','budgie-desktop-symbolic'])
+ except CalledProcessError:
+ Popen(['notify-send','Kinto: Error Resetting AltGr!','-i','budgie-desktop-symbolic'])
return
@@ -282,12 +499,12 @@ class Indicator():
cmds = ['perl','-pi','-e',setkb,self.kconfig]
- cmdsTerm = subprocess.Popen(cmds)
+ cmdsTerm = Popen(cmds)
restartsvc = True
- except subprocess.CalledProcessError:
- subprocess.Popen(['notify-send','Kinto: Error Resetting SublimeText remaps for VSCode!','-i','budgie-desktop-symbolic'])
+ except CalledProcessError:
+ Popen(['notify-send','Kinto: Error Resetting SublimeText remaps for VSCode!','-i','budgie-desktop-symbolic'])
return
def setCaps2Esc(self,button):
@@ -306,12 +523,12 @@ class Indicator():
else:
self.caps2cmd.set_sensitive(True)
- cmdsTerm = subprocess.Popen(cmds)
+ cmdsTerm = Popen(cmds)
restartsvc = True
- except subprocess.CalledProcessError:
- subprocess.Popen(['notify-send','Kinto: Error resetting caps2esc!','-i','budgie-desktop-symbolic'])
+ except CalledProcessError:
+ Popen(['notify-send','Kinto: Error resetting caps2esc!','-i','budgie-desktop-symbolic'])
return
@@ -332,66 +549,120 @@ class Indicator():
else:
self.caps2esc.set_sensitive(True)
- cmdsTerm = subprocess.Popen(cmds)
+ cmdsTerm = Popen(cmds)
restartsvc = True
- except subprocess.CalledProcessError:
- subprocess.Popen(['notify-send','Kinto: Error resetting caps2cmd!','-i','budgie-desktop-symbolic'])
+ except CalledProcessError:
+ Popen(['notify-send','Kinto: Error resetting caps2cmd!','-i','budgie-desktop-symbolic'])
return
+ def runRestart(self,button):
+ try:
+ stop = Popen(['sudo', 'systemctl','stop','xkeysnail'])
+ stop.wait()
+ time.sleep(1)
+ res = Popen(['pgrep','xkeysnail'])
+ res.wait()
+
+ if res.returncode == 0:
+ # Popen(['notify-send','Kinto: Ending Debug','-i','budgie-desktop-symbolic'])
+ pkillxkey = Popen(['sudo', 'pkill','-f','bin/xkeysnail'])
+ pkillxkey.wait()
+
+ Popen(['sudo', 'systemctl','start','xkeysnail'])
+ except:
+ Popen(['notify-send','Kinto: Error restarting Kinto!','-i','budgie-desktop-symbolic'])
+ # self.checkbox_enable.set_active(False)
+ # self.checkbox_enable.disconnect(self.enable_id)
+ # self.enable_id = self.checkbox_enable.connect('activate',self.setEnable,True)
+ # self.indicator.set_icon(os.environ['HOME']+'/.config/kinto/kinto-color.svg')
+
+ def runDebug(self,button):
+ try:
+ Popen([os.environ['HOME']+'/Documents/git-projects/kinto/xkeysnail-config/gui/kinto-gui.py','-d'])
+ except:
+ Popen(['notify-send','Kinto: Error restarting Kinto!','-i','budgie-desktop-symbolic'])
+ self.checkbox_enable.set_active(False)
+ self.checkbox_enable.disconnect(self.enable_id)
+ self.enable_id = self.checkbox_enable.connect('activate',self.setEnable,True)
+ # self.indicator.set_icon(os.environ['HOME']+'/.config/kinto/kinto-color.svg')
+
def queryConfig(self,query):
- res = subprocess.Popen(query, stdout=subprocess.PIPE, stderr=None, shell=True)
+ res = Popen(query, stdout=PIPE, stderr=None, shell=True)
res.wait()
return res.communicate()[0].strip().decode('UTF-8')
def setEnable(self,button,enableKinto):
try:
if enableKinto:
- subprocess.Popen(['sudo', 'systemctl','restart','xkeysnail'])
- self.checkbox_enable.set_active(True)
+ res = Popen(['pgrep','xkeysnail'])
+ res.wait()
+ print(res.returncode)
+
+ if res.returncode == 0:
+ # Popen(['notify-send','Kinto: Err in debug mode?','-i','budgie-desktop-symbolic'])
+ pkillxkey = Popen(['sudo', 'pkill','-f','bin/xkeysnail'])
+ pkillxkey.wait()
+
+ Popen(['sudo', 'systemctl','restart','xkeysnail'])
self.checkbox_enable.disconnect(self.enable_id)
+ self.checkbox_enable.set_active(True)
self.enable_id = self.checkbox_enable.connect('activate',self.setEnable,False)
- self.indicator.set_icon(self.homedir+'/.config/kinto/kinto-invert.svg')
+ self.indicator.set_icon(os.environ['HOME']+'/.config/kinto/kinto-invert.svg')
else:
- subprocess.Popen(['sudo', 'systemctl','stop','xkeysnail'])
- self.checkbox_enable.set_active(False)
+ Popen(['sudo', 'systemctl','stop','xkeysnail'])
self.checkbox_enable.disconnect(self.enable_id)
+ self.checkbox_enable.set_active(False)
self.enable_id = self.checkbox_enable.connect('activate',self.setEnable,True)
- self.indicator.set_icon(self.homedir+'/.config/kinto/kinto-color.svg')
+ self.indicator.set_icon(os.environ['HOME']+'/.config/kinto/kinto.svg')
- except subprocess.CalledProcessError:
- subprocess.Popen(['notify-send','Kinto: Error enabling!','-i','budgie-desktop-symbolic'])
+ self.unixts = int(time.time())
+
+ except CalledProcessError:
+ Popen(['notify-send','Kinto: Error enabling!','-i','budgie-desktop-symbolic'])
def setAutostart(self,button,autostart):
try:
if autostart == False:
- subprocess.Popen(['perl','-pi','-e','s/autostart = true/autostart = false/g',self.homedir+'/.config/kinto/kinto.py'])
+ Popen(['perl','-pi','-e','s/autostart = true/autostart = false/g',os.environ['HOME']+'/.config/kinto/kinto.py'])
self.checkbox_autostart.set_active(False)
self.checkbox_autostart.disconnect(self.chkautostart_id)
self.chkautostart_id = self.checkbox_autostart.connect('activate',self.setAutostart,True)
else:
- subprocess.Popen(['perl','-pi','-e','s/autostart = false/autostart = true/g',self.homedir+'/.config/kinto/kinto.py'])
+ Popen(['perl','-pi','-e','s/autostart = false/autostart = true/g',os.environ['HOME']+'/.config/kinto/kinto.py'])
self.checkbox_autostart.set_active(True)
self.checkbox_autostart.disconnect(self.chkautostart_id)
self.chkautostart_id = self.checkbox_autostart.connect('activate',self.setAutostart,False)
- except subprocess.CalledProcessError:
- subprocess.Popen(['notify-send','Kinto: Error setting autostart!','-i','budgie-desktop-symbolic'])
+ except CalledProcessError:
+ Popen(['notify-send','Kinto: Error setting autostart!','-i','budgie-desktop-symbolic'])
def setConfig(self,button):
try:
if os.path.exists('/opt/sublime_text/sublime_text'):
- subprocess.Popen(['/opt/sublime_text/sublime_text',self.homedir+'/.config/kinto/kinto.py'])
+ Popen(['/opt/sublime_text/sublime_text',os.environ['HOME']+'/.config/kinto/kinto.py'])
elif which(gedit) is not None:
- subprocess.Popen(['gedit',self.homedir+'/.config/kinto/kinto.py'])
+ Popen(['gedit',os.environ['HOME']+'/.config/kinto/kinto.py'])
elif which(mousepad) is not None:
- subprocess.Popen(['mousepad',self.homedir+'/.config/kinto/kinto.py'])
+ Popen(['mousepad',os.environ['HOME']+'/.config/kinto/kinto.py'])
- except subprocess.CalledProcessError: # Notify user about error on running restart commands.
- subprocess.Popen(['notify-send','Kinto: Error could not open config file!','-i','budgie-desktop-symbolic'])
+ except CalledProcessError: # Notify user about error on running restart commands.
+ Popen(['notify-send','Kinto: Error could not open config file!','-i','budgie-desktop-symbolic'])
+
+ def setService(self,button):
+ try:
+ if os.path.exists('/opt/sublime_text/sublime_text'):
+ Popen(['/opt/sublime_text/sublime_text','/lib/systemd/system/xkeysnail.service'])
+ elif which(gedit) is not None:
+ Popen(['gedit','/lib/systemd/system/xkeysnail.service'])
+ elif which(mousepad) is not None:
+ Popen(['mousepad','/lib/systemd/system/xkeysnail.service'])
+
+ except CalledProcessError: # Notify user about error on running restart commands.
+ Popen(['notify-send','Kinto: Error could not open config file!','-i','budgie-desktop-symbolic'])
def setKB(self,button,kbtype):
try:
@@ -433,25 +704,25 @@ class Indicator():
restart = ['sudo', 'systemctl','restart','xkeysnail']
cmds = ['perl','-pi','-e',setkb,self.kconfig]
- cmdsTerm = subprocess.Popen(cmds)
+ cmdsTerm = Popen(cmds)
cmdsTerm.wait()
- subprocess.Popen(restart)
+ Popen(restart)
- except subprocess.CalledProcessError:
- subprocess.Popen(['notify-send','Kinto: Error Resetting KB Type!','-i','budgie-desktop-symbolic'])
+ except CalledProcessError:
+ Popen(['notify-send','Kinto: Error Resetting KB Type!','-i','budgie-desktop-symbolic'])
def setSysKB(self,button):
if self.ostype == "XFCE":
- subprocess.Popen(['xfce4-keyboard-settings'])
+ Popen(['xfce4-keyboard-settings'])
else:
- subprocess.Popen(['gnome-control-center','keyboard'])
+ Popen(['gnome-control-center','keyboard'])
def setRegion(self,button):
if self.ostype == "XFCE":
- subprocess.Popen(['gnome-language-selector'])
+ Popen(['gnome-language-selector'])
else:
- subprocess.Popen(['gnome-control-center','region'])
+ Popen(['gnome-control-center','region'])
def quit(source):
Gtk.main_quit()
diff --git a/xkeysnail_service.sh b/xkeysnail_service.sh
index b5cddd7..25357c0 100755
--- a/xkeysnail_service.sh
+++ b/xkeysnail_service.sh
@@ -324,6 +324,7 @@ if [[ $1 == "1" || $1 == "2" || $1 == "3" || $1 == "4" || $1 == "winmac" || $1 =
sed -i "s/{username}/`whoami`/g" ./xkeysnail-config/limitedadmins.new
sed -i "s#{systemctl}#`\\which systemctl`#g" ./xkeysnail-config/limitedadmins.new
sed -i "s#{pkill}#`\\which pkill`#g" ./xkeysnail-config/limitedadmins.new
+ sed -i "s#{xkeysnail}#/usr/local/bin/xkeysnail#g" ./xkeysnail-config/limitedadmins.new
sudo chown root:root ./xkeysnail-config/limitedadmins.new
sudo mv ./xkeysnail-config/limitedadmins.new /etc/sudoers.d/limitedadmins
sed -i "s#{systemctl}#`\\which systemctl`#g" ~/.config/autostart/xkeysnail.desktop
@@ -394,6 +395,7 @@ fi
if [[ $1 == "1" || $1 == "2" || $1 == "3" || $1 == "winmac" || $1 == "mac" || $1 == "chromebook" ]]; then
mv ./xkeysnail-config/kinto.py.new ~/.config/kinto/kinto.py
+ git describe --tags | perl -ne "print \"\$1 build `git rev-parse --short HEAD`\n\" for m/\b(.*)-\w+-\w{8}/" > ~/.config/kinto/version
# if [ "$distro" == "fedora" ];then
sudo rm /etc/systemd/system/xkeysnail.service
if [ -d /usr/lib/systemd/system ];then