Compare commits

..

48 Commits

Author SHA1 Message Date
Ben Reaves
50885a7e78 Merge pull request #31 from rbreaves/dev
- Refactored kintox11 to fix multiple app category bug
2020-02-14 18:46:43 +00:00
Ben Reaves
ea60bb6db5 - Refactored kintox11 to fix multiple app category bug 2020-02-14 12:44:34 -06:00
Ben Reaves
4281d97c3d Merge pull request #30 from alexmyczko/patch-1
Makefile for .c source
2020-02-13 15:16:53 +00:00
Alex Myczko
364536b8ea Update Makefile 2020-02-13 08:33:01 +01:00
Alex Myczko
2585ab9f45 Update Makefile 2020-02-13 08:21:10 +01:00
Alex Myczko
7969bd007d Create Makefile 2020-02-13 08:19:13 +01:00
Ben Reaves
5d135afe5e Merge pull request #29 from rbreaves/dev
- word-wise update
2020-02-13 01:58:51 +00:00
Ben Reaves
a4fa9b225e - word-wise update for Alt+Left/Right to send cursor to begin/end of word while in GUI apps. 2020-02-12 19:53:10 -06:00
Ben Reaves
eac62fb605 - Improved Open Display function to timeout after 60 seconds, fixes possible startup failure on boot for some distros. 2020-02-11 17:36:08 -06:00
Ben Reaves
ab679ddf9d - Improved Open Display function in kintox11 to retry for 1 minute, may be helpful in some distro configs. 2020-02-11 17:29:05 -06:00
Ben Reaves
f4cef736be - Updated kintox11 binary to handle errors better in the get top window function 2020-02-11 15:40:16 -06:00
Ben Reaves
2179176881 - The beginnings of a python based xlib implementation of kintox11 2020-02-06 20:05:47 -06:00
Ben Reaves
26f70ccd31 - Updated kintox11 binary to handle errors better in the get top window function 2020-02-06 16:33:23 -06:00
Ben Reaves
0ff7a42f9b - Updated readme with more troubleshooting tips 2020-02-05 16:29:36 -06:00
Ben Reaves
58da4fcd90 Merge branch 'master' into dev 2020-02-05 16:06:41 -06:00
Ben Reaves
20170f0a7d - Removed the explicit reference to bin bash in the service file, also removed the Environment variable to avoid issues for when Display is not 0. 2020-02-05 16:05:41 -06:00
Ben Reaves
d90829928b Merge pull request #27 from rbreaves/dev
Fixes tweak selection during install
2020-02-05 21:35:03 +00:00
Ben Reaves
6f913538e8 - Fixed tweak selection in python installer 2020-02-05 15:33:51 -06:00
Ben Reaves
7dfbe884ff - Added medium article in readme 2020-02-05 14:11:13 -06:00
Ben Reaves
3a115f91ae Merge branch 'dev' 2020-02-05 14:06:57 -06:00
Ben Reaves
4c218b55bd - Updated uninstaller to remove kinto.desktop from startup 2020-02-05 14:06:37 -06:00
Ben Reaves
94cd3ed907 Merge pull request #26 from rbreaves/dev
Kintox11 binary will now always apply gui keymap on init unless a term app has focus
2020-02-05 19:56:20 +00:00
Ben Reaves
b0bde4fecf Merge branch 'master' into dev 2020-02-05 13:54:20 -06:00
Ben Reaves
b930b96066 - Fixed kintox11 to always apply gui keymap on initialization unless a term app has focus. (aka boot and user logoff/logon) 2020-02-05 13:52:25 -06:00
Ben Reaves
2df4920344 Merge pull request #25 from rbreaves/dev
- Corrected path of systemctl for desktop autostart file
2020-02-05 19:17:40 +00:00
Ben Reaves
ce9c80a02f - Corrected path of systemctl for desktop autostart file 2020-02-05 13:17:13 -06:00
Ben Reaves
e599562ec1 Merge pull request #24 from rbreaves/dev
- Added desktop startup of kinto service
2020-02-05 11:28:15 +00:00
Ben Reaves
b8b81bd907 - Added desktop startup of kinto service 2020-02-05 05:24:40 -06:00
Ben Reaves
22e5462fbc Merge pull request #23 from rbreaves/dev
Updated service
2020-02-05 10:22:55 +00:00
Ben Reaves
72d2007267 - Added restartsec interval on service to 1 second to try and avoid burst limit of systemd 2020-02-05 04:19:44 -06:00
Ben Reaves
3c5b49324c - Removed the creation of the autostart folder 2020-02-05 04:09:20 -06:00
Ben Reaves
3f37ef6e28 - Added back in the enable command for the keyswap service. 2020-02-05 04:01:17 -06:00
Ben Reaves
35cfcce748 Merge pull request #22 from rbreaves/dev
Updated kintox11 binary with better error handling
2020-02-05 09:20:05 +00:00
Ben Reaves
d288048ed4 - Due to updates in kintox11 error handling the services timer is no longer needed, the application will restart properly if it encounters an unrecoverable error on boot, login or any other unexpected event. 2020-02-05 03:01:22 -06:00
Ben Reaves
a30671b08c - Enabled full error handling 2020-02-05 02:47:53 -06:00
Ben Reaves
2f2afecb6d - Added more verbosity to kintox11 and added more functions to increase accuracy of the keyswap on all windows 2020-02-05 02:41:47 -06:00
Ben Reaves
072249d5d4 - Corrected chromebook config file and updated the initialization of the keyswap service file to work when re-running the installer on a currently running version of kinto 2020-02-05 00:12:44 -06:00
Ben Reaves
a6b9b1ffbb Merge pull request #21 from rbreaves/dev
- Fixes login/logout and reboot startup issues
2020-02-05 01:48:19 +00:00
Ben Reaves
d8c516c13c - Fixes login/logout and reboot startup issues, delays the start by 5 seconds 2020-02-04 19:45:39 -06:00
Ben Reaves
b763703d70 Merge pull request #19 from rbreaves/dev
App breaking bug resolved and improved initialization on boot
2020-02-04 22:02:38 +00:00
Ben Reaves
ecaf413fa4 - Removed 5 second restart delay, I think the new changes makes it irrelevant 2020-02-04 15:58:09 -06:00
Ben Reaves
48e01750e5 - Fixed breaking bug exception on how gui apps are initially handled. Also improved the initialization of kintox11. 2020-02-04 15:36:26 -06:00
Ben Reaves
5ec8c076a3 - Added more verbosity to the dynamic app output 2020-02-04 14:48:40 -06:00
Ben Reaves
c620b299bd - Added a more verbose initial startup to kintox11 for easier debugging purposes 2020-02-04 14:41:55 -06:00
Ben Reaves
496cb4d340 - Added O2 optimization to kintox11 binary 2020-02-03 22:52:19 -06:00
Ben Reaves
5f1e82fb24 - Fixed bug that prevented the new keymap from working under Chromebooks with Linux/GalliumOS 2020-02-03 16:27:59 -06:00
Ben Reaves
46e81640c6 - Updated readme again, keeping it shorter 2020-02-03 14:25:22 -06:00
Ben Reaves
1c56c98ab9 - Updated readme to properly link to releases and provide more info 2020-02-03 13:23:51 -06:00
16 changed files with 349 additions and 117 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
.env/
.DS_Store
__pycache__/

View File

@@ -1,15 +1,15 @@
default partial xkb_symbols "mac_levelssym" {
// LEFT to Begin Line
// LEFT to Begin Line or Beginning of word
replace key <LEFT> {
type[Group1]= "ONE_LEVEL_CTRL",
symbols[Group1]= [ Left, Left, NoSymbol ],
actions[Group1]= [ NoAction(), NoAction(), RedirectKey(key=<HOME>,clearmods=Control)]
actions[Group1]= [ NoAction(), RedirectKey(key=<LEFT>,modifiers=Control,clearmods=Mod1), RedirectKey(key=<HOME>,clearmods=Control)]
};
// Right to End of Line
// Right to End of Line or end of word
replace key <RGHT> {
type[Group1]= "ONE_LEVEL_CTRL",
symbols[Group1]= [ Right, Right, NoSymbol ],
actions[Group1]= [ NoAction(), NoAction(), RedirectKey(key=<END>,clearmods=Control)]
actions[Group1]= [ NoAction(), RedirectKey(key=<RGHT>,modifiers=Control,clearmods=Mod1), RedirectKey(key=<END>,clearmods=Control)]
};
// Up to Mac Home
replace key <UP> {

View File

@@ -0,0 +1,14 @@
default partial xkb_symbols "mac_levelssym" {
key <LALT> {
repeat= no,
type= "ONE_LEVEL",
symbols[Group1]= [ Hyper_L ],
actions[group1]=[ SetMods(modifiers=Shift+Control) ]
};
key <RALT> {
repeat= no,
type= "ONE_LEVEL",
symbols[Group1]= [ Hyper_R ],
actions[group1]=[ SetMods(modifiers=Shift+Control) ]
};
};

View File

@@ -1,20 +1,11 @@
default partial xkb_types "addmac_levels" {
type "ONE_LEVEL_CTRL" {
modifiers= Shift+Control;
map[Shift]= Level2;
modifiers= Mod1+Control;
map[Mod1]= Level2;
map[Control]= Level3;
map[Shift+Control]= Level3;
map[Mod1+Control]= Level3;
level_name[Level1]= "Base";
level_name[Level2]= "Caps";
level_name[Level3]= "With Control";
};
type "TWO_LEVEL_CTRL" {
modifiers= Shift+Control;
map[Shift]= Level2;
map[Control]= Level3;
map[Shift+Control]= Level3;
level_name[Level1]= "Base";
level_name[Level2]= "Caps";
level_name[Level2]= "Alt";
level_name[Level3]= "With Control";
};
};

View File

@@ -2,15 +2,13 @@
![alt text](https://raw.githubusercontent.com/rbreaves/kinto/master/Kinto.png)
[![GitHub release](https://img.shields.io/github/release/rbreaves/kinto.svg)](https://github.com/rbreaves/kinto/releases)
[![GitHub release](https://img.shields.io/github/release/rbreaves/kinto.svg)](https://github.com/rbreaves/kinto/releases/latest)
![alt text](https://github.com/rbreaves/kinto/blob/master/splash.png)
\- Type in Linux like it's a Mac. \-
Memory muscle matters for programmers and developers.
If it happens on your mac keyboard then it should happen the same in linux.
Cmd = Ctrl+Shift for all terminals.
Note: As of version 1.0 Kinto no longer maps Cmd/Alt to Super while using the Terminal, it is now mapping to Ctrl+Shift by default. Please reset your terminal's keymaps back to their defaults.
@@ -167,19 +165,41 @@ systemctl --user stop keyswap && setxkbmap -option;setxkbmap -option altwin:swap
## Troubleshooting
### Does not start when you log in or after you reboot?
1. Check the status
```
systemctl --user status keyswap
```
2. Check the service journal
```
journalctl -xe
```
Open a ticket and send me the info.
### Keyswap is not occurring, but it was working.
Now that Kinto is using a custom written C program I am not aware of any specific bugs or issues, but you can start here if you having difficulties and please report it if it is reproducible.
1. Restart Kinto
1. Get status
```
systemctl --user status keyswap
```
2. Restart Kinto
```
systemctl --user restart keyswap
```
2. Check the Status of Kinto and open a ticket with the output.
3. Check the Status again and open a ticket if you need to.
```
systemctl --user status keyswap
```
You can also do the following to see if it is an actual issue with kintox11 not running or your service file.
```
cd ~/.config/kinto
./kintox11
```
## Language Support
I'd appreciate any help from people with non-US based keyboards, to help ensure that these keymaps and keyswap methods work in all or most languages.
@@ -196,6 +216,7 @@ https://superuser.com/questions/385748/binding-superc-superv-to-copy-and-paste
## More information about Kinto
https://medium.com/@benreaves/kinto-v1-0-released-2018e6401d2e
https://medium.com/@benreaves/kinto-a-mac-inspired-keyboard-mapping-for-linux-58f731817c0
## License

View File

@@ -49,10 +49,10 @@
"type":"chromebook",
"active": false,
"description":"Standard Chromebook Keyboards",
"gui":"setxkbmap -option;xkbcomp -w0 -I$HOME/.xkb ~/.xkb/keymap/kbd.chromebook.gui $DISPLAY",
"gui":"setxkbmap -option;xkbcomp -w0 -I$HOME/.xkb ~/.xkb/keymap/kbd.mac.gui $DISPLAY",
"term":"setxkbmap -option;xkbcomp -w0 -I$HOME/.xkb ~/.xkb/keymap/kbd.mac.term $DISPLAY",
"xkb_symbols_gui":"+chromebook(swap_lalt_lctrl)+mac_gui(mac_levelssym)",
"xkb_symbols_term":"+altwin(swap_alt_win)+mac_term(mac_levelssym)",
"xkb_symbols_term":"+altwin(swap_alt_win)+mac_term_chromebook(mac_levelssym)",
"xkb_types_gui":"+mac_gui(addmac_levels)",
"xkb_types_term":""
},
@@ -62,11 +62,11 @@
"type":"chromebook",
"active": false,
"description":"Chromebook with Windows 104 Keyboard",
"gui":"setxkbmap -option;xkbcomp -w0 -I$HOME/.xkb ~/.xkb/keymap/kbd.chromebook.gui $DISPLAY; setxkbmap -device $usbid -option altwin:ctrl_alt_win",
"gui":"setxkbmap -option;xkbcomp -w0 -I$HOME/.xkb ~/.xkb/keymap/kbd.mac.gui $DISPLAY; setxkbmap -device $usbid -option altwin:ctrl_alt_win",
"term":"setxkbmap -option;xkbcomp -w0 -I$HOME/.xkb ~/.xkb/keymap/kbd.mac.term $DISPLAY",
"fallbackgui":"setxkbmap -option;xkbcomp -w0 -I$HOME/.xkb ~/.xkb/keymap/kbd.chromebook.gui $DISPLAY",
"fallbackgui":"setxkbmap -option;xkbcomp -w0 -I$HOME/.xkb ~/.xkb/keymap/kbd.mac.gui $DISPLAY",
"xkb_symbols_gui":"+chromebook(swap_lalt_lctrl)+mac_gui(mac_levelssym)",
"xkb_symbols_term":"+altwin(swap_alt_win)+mac_term(mac_levelssym)",
"xkb_symbols_term":"+altwin(swap_alt_win)+mac_term_chromebook(mac_levelssym)",
"xkb_types_gui":"+mac_gui(addmac_levels)",
"xkb_types_term":""
},
@@ -76,10 +76,10 @@
"type":"chromebook",
"active": false,
"description":"Chromebook with Mac Keyboard",
"gui":"setxkbmap -option;setxkbmap -option ctrl:swap_lwin_lctl; xkbcomp -w0 -i $internalid -I$HOME/.xkb ~/.xkb/keymap/kbd.chromebook.gui $DISPLAY",
"gui":"setxkbmap -option;setxkbmap -option ctrl:swap_lwin_lctl; xkbcomp -w0 -i $internalid -I$HOME/.xkb ~/.xkb/keymap/kbd.mac.gui $DISPLAY",
"term":"setxkbmap -option;xkbcomp -w0 -I$HOME/.xkb ~/.xkb/keymap/kbd.mac.term $DISPLAY",
"xkb_symbols_gui":"+chromebook(swap_lalt_lctrl)+mac_gui(mac_levelssym)",
"xkb_symbols_term":"+altwin(swap_alt_win)+mac_term(mac_levelssym)",
"xkb_symbols_term":"+altwin(swap_alt_win)+mac_term_chromebook(mac_levelssym)",
"xkb_types_gui":"+mac_gui(addmac_levels)",
"xkb_types_term":""
}]

View File

@@ -1,13 +1,18 @@
#!/bin/bash
swapcmd="\/bin\/bash\ \/home\/`whoami`\/.config\/kinto\/xactive.sh"
systemctl --user stop keyswap >/dev/null 2>&1
systemctl --user disable keyswap >/dev/null 2>&1
systemctl --user stop keyswap.timer >/dev/null 2>&1
systemctl --user disable keyswap.timer >/dev/null 2>&1
swapcmd="\/home\/`whoami`\/.config\/kinto\/xactive.sh"
mkdir -p ~/.config/systemd/user
mkdir -p ~/.config/autostart
cp ./system-config/keyswap.service ~/.config/systemd/user/keyswap.service
cp ./system-config/keyswap.sh ~/.config/autostart/keyswap.sh
cp ./system-config/kinto.desktop ~/.config/autostart/kinto.desktop
cp ./kintox11/binary/kintox11 ~/.config/kinto/kintox11
cp ./system-config/xactive.sh ~/.config/kinto/xactive.sh
sed -i "s/{username}/`whoami`/g" ~/.config/systemd/user/keyswap.service
sed -i "s/ExecStart=/ExecStart=${swapcmd}/g" ~/.config/systemd/user/keyswap.service
systemctl --user daemon-reload
systemctl --user enable keyswap
systemctl --user start keyswap
systemctl --user start keyswap

115
kintopy/kinto.py Normal file
View File

@@ -0,0 +1,115 @@
#!/usr/bin/env python
#
# Kinto - Python implementation of Xlib
#
# Based on code by Stephan Sokolow
# Source: https://gist.github.com/ssokolow/e7c9aae63fb7973e4d64cff969a78ae8
from contextlib import contextmanager
import Xlib
import Xlib.display
# Connect to the X server and get the root window
disp = Xlib.display.Display()
root = disp.screen().root
# Prepare the property names we use so they can be fed into X11 APIs
NET_ACTIVE_WINDOW = disp.intern_atom('_NET_ACTIVE_WINDOW')
NET_WM_NAME = disp.intern_atom('_NET_WM_NAME') # UTF-8
WM_NAME = disp.intern_atom('WM_NAME') # Legacy encoding
NET_WM_CLASS = disp.intern_atom('_NET_WM_CLASS') # UTF-8
WM_CLASS = disp.intern_atom('WM_CLASS')
last_seen = { 'xid': None, 'title': None }
@contextmanager
def window_obj(win_id):
"""Simplify dealing with BadWindow (make it either valid or None)"""
window_obj = None
if win_id:
try:
window_obj = disp.create_resource_object('window', win_id)
except Xlib.error.XError:
pass
yield window_obj
def get_active_window():
"""Return a (window_obj, focus_has_changed) tuple for the active window."""
win_id = root.get_full_property(NET_ACTIVE_WINDOW,Xlib.X.AnyPropertyType).value[0]
focus_changed = (win_id != last_seen['xid'])
if focus_changed:
with window_obj(last_seen['xid']) as old_win:
if old_win:
old_win.change_attributes(event_mask=Xlib.X.NoEventMask)
last_seen['xid'] = win_id
with window_obj(win_id) as new_win:
if new_win:
new_win.change_attributes(event_mask=Xlib.X.PropertyChangeMask)
return win_id, focus_changed
def _get_window_class_inner(win_obj):
for atom in (NET_WM_CLASS, WM_CLASS):
try:
window_class = win_obj.get_full_property(atom, 0)
except UnicodeDecodeError: # Apparently a Debian distro package bug
title = "<could not decode characters>"
else:
if window_class:
win_class = window_class.value.split('\x00')[1]
if isinstance(win_class, bytes):
# Apparently COMPOUND_TEXT is so arcane that this is how
# tools like xprop deal with receiving it these days
win_class = win_class.split('\x00')[1].decode('latin1', 'replace')
return win_class
else:
title = "<unnamed window>"
return "{} (XID: {})".format(title, win_obj.id)
def get_window_class(win_id):
"""Look up the window name for a given X11 window ID"""
if not win_id:
last_seen['title'] = "<no window id>"
return last_seen['title']
title_changed = False
with window_obj(win_id) as wobj:
if wobj:
win_title = _get_window_class_inner(wobj)
title_changed = (win_title != last_seen['title'])
last_seen['title'] = win_title
return last_seen['title'], title_changed
def handle_xevent(event):
# Loop through, ignoring events until we're notified of focus/title change
if event.type != Xlib.X.PropertyNotify:
return
changed = False
if event.atom == NET_ACTIVE_WINDOW:
if get_active_window()[1]:
changed = changed or get_window_class(last_seen['xid'])[1]
elif event.atom in (NET_WM_CLASS, WM_CLASS):
changed = changed or get_window_class(last_seen['xid'])[1]
if changed:
handle_change(last_seen)
def handle_change(new_state):
"""Replace this with whatever you want to actually do"""
print(new_state['title'])
if __name__ == '__main__':
# Listen for _NET_ACTIVE_WINDOW changes
root.change_attributes(event_mask=Xlib.X.PropertyChangeMask)
# Prime last_seen with whatever window was active when we started this
get_window_class(get_active_window()[0])
handle_change(last_seen)
while True: # next_event() sleeps until we get an event
handle_xevent(disp.next_event())

Binary file not shown.

5
kintox11/src/Makefile Normal file
View File

@@ -0,0 +1,5 @@
CFLAGS=-g $(shell pkg-config --cflags json-c xmu)
LDFLAGS=-g $(shell pkg-config --libs json-c xmu)
all:
$(CC) kintox11.c $(CFLAGS) $(LDFLAGS) -o kintox11

View File

@@ -10,7 +10,7 @@
//
// To compile with static library json-c
// Make sure archive with object files exist ar -t /usr/local/lib/libjson-c.a
// gcc -L/usr/local/lib/ kintox11.c -ljson-c -lXmu -lXt -lX11 -o kintox11
// gcc -L/usr/local/lib/ kintox11.c -ljson-c -lXmu -lXt -lX11 -O2 -o kintox11
//
#include <stdlib.h>
@@ -18,6 +18,7 @@
#include <locale.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <X11/Xlib.h> // `apt-get install libx11-dev`
#include <X11/Xmu/WinUtil.h> // `apt-get install libxmu-dev`
#include <json-c/json.h> // `apt install libjson-c-dev`
@@ -58,19 +59,30 @@ int strcicmp(char const *a, char const *b)
}
Display* open_display(){
int i;
Display* d = XOpenDisplay(NULL);
for (i = 0; i < 60; i++) {
if(d == NULL){
printf("fail to open X server display...\n");
}
else{
break;
}
sleep(1);
}
if(d == NULL){
printf("fail to open X server display...\n");
printf("fail to open X server display for 1 minute...\n");
printf("Kintox11 is now exiting...\n");
exit(1);
}
return d;
}
int handle_error(Display* display, XErrorEvent* error){
// printf("X11 error: type=%d, serial=%lu, code=%d\n",
// error->type, error->serial, (int)error->error_code);
// xerror = True;
return 0;
printf("X11 error: type=%d, serial=%lu, code=%d\n",
error->type, error->serial, (int)error->error_code);
xerror = True;
return 1;
}
Window get_focus_window(Display* d){
@@ -88,6 +100,49 @@ Window get_focus_window(Display* d){
return w;
}
// get the top window.
// a top window have the following specifications.
// * the start window is contained the descendent windows.
// * the parent window is the root window.
Window get_top_window(Display* d, Window start){
Window w = start;
Window parent = start;
Window root = None;
Window *children;
unsigned int nchildren;
Status s;
while (parent != root && parent != 0) {
w = parent;
s = XQueryTree(d, w, &root, &parent, &children, &nchildren); // see man
if (s)
XFree(children);
if(xerror){
printf("fail to get top window: %ld\n",w);
exit(1);
}
// printf(" get parent (window: %d)\n", (int)w);
}
// printf("success (window: %d)\n", (int)w);
return w;
}
// search a named window (that has a WM_STATE prop)
// on the descendent windows of the argment Window.
Window get_named_window(Display* d, Window start){
Window w;
// printf("getting named window ... ");
w = XmuClientWindow(d, start); // see man
// if(w == start)
// printf("fail\n");
// printf("success (window: %d)\n", (int) w);
return w;
}
const char * str_window_class(Display* d, Window w, char *prior_app ){
Status s;
@@ -128,7 +183,8 @@ int main(void){
int system(const char *command);
size_t i,n,r;
printf("Importing user_config.json...\n");
fp = fopen("user_config.json","r");
fread(buffer, 10240, 1, fp);
fclose(fp);
@@ -209,13 +265,13 @@ int main(void){
}
else{
appnames_array[i][n] = json_object_get_string(json_object_array_get_idx(config_obj_appnames, n));
// printf("%s i:%ld n:%ld %s\n",name_array[i],i,n,appnames_array[i][n]);
//printf("%s i:%ld n:%ld %s\n",name_array[i],i,n,appnames_array[i][n]);
}
}
if(appnames_max > appnames_len){
for (n = appnames_len; n < appnames_max; n++){
appnames_array[i][n] = NULL;
// printf("%s i:%ld n:%ld %s\n",name_array[i],i,n,appnames_array[i][n]);
//printf("%s i:%ld n:%ld %s\n",name_array[i],i,n,appnames_array[i][n]);
}
}
@@ -233,6 +289,8 @@ int main(void){
}
}
printf("Data from user_config.json imported successfully.\n");
for (i = 0; i < init_len; i++) {
init_array[i] = json_object_get_int(json_object_array_get_idx(init, i));
@@ -243,6 +301,7 @@ int main(void){
Display* d;
Window w;
char *name;
// for XmbTextPropertyToTextList
setlocale(LC_ALL, ""); // see man locale
@@ -252,89 +311,102 @@ int main(void){
XSetErrorHandler(handle_error);
char * prior_app;
char * current_app;
char * prior_category;
char * current_category;
prior_app = malloc(sizeof(char)*100);
current_app = malloc(sizeof(char)*100);
prior_category = malloc(sizeof(char)*100);
current_category = malloc(sizeof(char)*100);
strcpy(prior_app,"none");
strcpy(prior_category,"none");
int remap_bool = 2;
printf("Starting keyswap...\n");
// get active window
w = get_focus_window(d);
w = get_top_window(d, w);
w = get_named_window(d, w);
// XFetchName(d, w, &name);
// printf("window:%#x name:%s\n", w, name);
printf("First window name: %s \n",str_window_class(d, w,prior_app));
int breakouter;
for (;;)
{
breakouter = 0;
// printf("%s\n","1");
// printf("%s\n",str_window_class(d, w,prior_app));
if(strcmp(str_window_class(d, w,prior_app),prior_app)){
// printf("%s\n","2");
for(i = 0; i < arraylen; ++i){
if(breakouter == 0){
if(strcmp(name_array[i],"gui")){
// printf("%s\n","3");
for(n = 0; n < appnames_max; ++n){
if (appnames_array[i][n] != NULL){
// printf("%s\n",appnames_array[i][n]);
// If statement for triggering terminal config
if((strcicmp(appnames_array[i][n], str_window_class(d, w,prior_app)) == 0 && (remap_bool == 1 || remap_bool == 2))) {
// printf("1st if %s i:%ld n:%ld %s\n",name_array[i],i,n,appnames_array[i][n]);
printf("%s\n",name_array[i]);
system(run_array[i]);
for(r = 0; r < config_de_max; r++){
if(config_de_array[i][r] != -1){
int de_id_idx = in_int(de_id_array, de_len, config_de_array[i][r]);
// printf("Running de command: %s\n",de_run_array[de_id_idx]);
system(de_runterm_array[de_id_idx]);
}
}
remap_bool = 0;
fflush(stdout);
breakouter = 1;
break;
} // Else command for ignoring similar app category based on config
else if((strcicmp(appnames_array[i][n], str_window_class(d, w,prior_app)) == 0 && remap_bool == 0)){
// printf("2nd elseif %s i:%ld n:%ld %s\n",name_array[i],i,n,appnames_array[i][n]);
// printf("%s\n","4");
breakouter = 1;
break;
} // Else command for triggering gui config
else if ((i == arraylen-1 || appnames_array[i][n+1] == NULL) && (remap_bool == 0 || remap_bool == 2)){
char *find = "gui";
int gui_idx = in(name_array, arraylen, find);
if(gui_idx >= 0) {
printf("%s\n",name_array[gui_idx]);
system(run_array[gui_idx]);
}
for(r = 0; r < config_de_max; r++){
if(config_de_array[gui_idx][r] != -1){
int de_id_idx = in_int(de_id_array, de_len, config_de_array[gui_idx][r]);
// printf("Running de command: %s\n",de_run_array[de_id_idx]);
system(de_rungui_array[de_id_idx]);
}
}
// printf("3rd elseif %s i:%ld n:%ld %s\n",name_array[i],i,n,appnames_array[i][n]);
remap_bool = 1;
fflush(stdout);
breakouter = 1;
break;
}
}
}
strcpy(current_app,str_window_class(d, w,prior_app));
int category_idx;
// printf("current: %s\n",current_app);
breakouter = 0;
// Cycle through category name array
// printf("%d\n",arraylen);
for(i = 0; i < arraylen; ++i){
// Cycle through the maximum App name array in each category
for(n = 0; n < appnames_max; ++n){
if (appnames_array[i][n] != NULL){
// printf("%s\n",appnames_array[i][n]);
if(strcicmp(appnames_array[i][n], current_app) == 0){
strcpy(current_category,name_array[i]);
category_idx = i;
// printf("Match found: %s: %s\n",current_category,current_app);
breakouter = 1;
break;
}
}
else{
else if(i == arraylen-1 && breakouter==0){
// printf("No match found, default to gui");
strcpy(current_category,"gui");
category_idx = in(name_array, arraylen, current_category);
// printf("Match found: %s: %s\n",current_category,current_app);
break;
}
else if(appnames_array[i][n] == NULL){
break;
}
if(breakouter==1){
break;
}
}
}
// printf("%s\n","5");
strcpy(prior_app,str_window_class(d, w, prior_app));
if(strcicmp(prior_category, current_category) != 0){
printf("%s: %s\n",current_category,current_app);
// printf("run: %s\n",run_array[category_idx]);
system(run_array[category_idx]);
for(r = 0; r < config_de_max; r++){
if(config_de_array[category_idx][r] != -1){
int de_id_idx = in_int(de_id_array, de_len, config_de_array[category_idx][r]);
if(strcicmp(current_category, "term") == 0){
// printf("Running de term command: %s\n",de_runterm_array[de_id_idx]);
system(de_runterm_array[de_id_idx]);
}
else{
// printf("Running de gui command: %s\n",de_rungui_array[de_id_idx]);
system(de_rungui_array[de_id_idx]);
}
}
}
}
else if(strcicmp(prior_app, current_app) != 0){
int indent = strlen(current_category)+2;
printf("%*c%s\n", indent, ' ',current_app);
}
fflush(stdout);
strcpy(prior_app,current_app);
strcpy(prior_category,current_category);
XEvent e;
XNextEvent(d, &e);
w = get_focus_window(d);
w = get_top_window(d, w);
w = get_named_window(d, w);
}
}

View File

@@ -130,23 +130,28 @@ if(onetime):
print("\nDynamic shortcut tweaks\n")
intents = [obj for obj in user_config['de'] if(obj['intent'] == "gui_term")]
tweaks = []
tweaks_selected = []
for index, k in enumerate(intents):
print(color_arr[default-1] + bcolors.BOLD + str(index+1) + '. ' + k['name'] + bcolors.ENDC)
print(bcolors.CYELLOW + 'Description: ' + k['description'] + bcolors.ENDC)
print(bcolors.CYELLOW + 'run in gui mode: ' + k['run_gui'].replace(";", "\n") + bcolors.ENDC)
print(bcolors.CYELLOW + 'run in terminal mode: ' + k['run_term'].replace(";", "\n") + bcolors.ENDC + '\n')
tweaks.append(k['id'])
print(bcolors.CYELLOW + "Please enter your dynamic shortcut tweak(s) (eg 1 or 1 2 3 - leave blank to skip): " + bcolors.ENDC)
defaultde = [int(i) for i in input().split()]
if len(defaultde) != 0:
# gui
user_config['config'][0]['de'] = defaultde
# term
user_config['config'][1]['de'] = defaultde
for d in defaultde:
user_config['de'][d-1]['active'] = True
user_config['de'][tweaks[d-1]]['active'] = True
tweaks_selected.append(tweaks[d-1])
if len(defaultde) != 0:
# gui
user_config['config'][0]['de'] = tweaks_selected
# term
user_config['config'][1]['de'] = tweaks_selected
user_config['config'][0]['run'] = keyboardconfigs[defaultkb-1]['gui']
user_config['config'][1]['run'] = keyboardconfigs[defaultkb-1]['term']

View File

@@ -4,10 +4,8 @@ PartOf=graphical-session.target
[Service]
Type=simple
#User={username}
#Group={username}
Environment=DISPLAY=:0
Restart=always
RestartSec=1
WorkingDirectory=/home/{username}/.config/kinto
ExecStart=

View File

@@ -1,3 +0,0 @@
#/bin/bash
systemctl --user start keyswap

View File

@@ -0,0 +1,8 @@
[Desktop Entry]
Name=Kinto
GenericName=Kinto
Comment=Make Linux Type Like it's a Mac
Exec=/usr/bin/systemctl --user start keyswap
Terminal=false
Type=Application
X-GNOME-Autostart-enabled=true

View File

@@ -2,7 +2,7 @@
systemctl --user stop keyswap
systemctl --user disable keyswap
rm -rf ~/.config/autostart/keyswap.sh
rm -rf ~/.config/autostart/kinto.desktop
rm -rf ~/.config/kinto
rm -rf ~/.xkb