diff --git a/bin/key-mapper-gtk b/bin/key-mapper-gtk
index 930df28e..d8e5fda0 100755
--- a/bin/key-mapper-gtk
+++ b/bin/key-mapper-gtk
@@ -28,7 +28,7 @@ from argparse import ArgumentParser
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('GLib', '2.0')
-from gi.repository import Gtk
+from gi.repository import Gtk, Gdk
from keymapper.data import get_data_path
from keymapper.X import create_setxkbmap_config, apply_preset, create_preset
@@ -41,6 +41,9 @@ from keymapper.linux import get_devices
window = None
+# TODO check for sudo rights
+
+
class SingleKeyMapping:
"""A single, configurable key mapping."""
def __init__(self, delete_callback):
@@ -54,24 +57,27 @@ class SingleKeyMapping:
def put_together(self):
"""Create all GTK widgets."""
- delete_button = Gtk.Button()
- destroy_icon = Gtk.Image.new_from_icon_name(
+ delete_button = Gtk.EventBox()
+ delete_button.add(Gtk.Image.new_from_icon_name(
'window-close', Gtk.IconSize.BUTTON
- )
- delete_button.set_image(destroy_icon)
- delete_button.connect('clicked', self.on_delete_button_clicked)
+ ))
+ delete_button.connect('button-press-event', self.on_delete_button_clicked)
+ delete_button.set_margin_start(5)
+ delete_button.set_margin_end(5)
key_code = Gtk.Entry()
key_code.set_alignment(0.5)
key_code.set_width_chars(4)
+ key_code.set_has_frame(False)
original_key = Gtk.Entry()
original_key.set_alignment(0.5)
original_key.set_width_chars(4)
+ original_key.set_has_frame(False)
- self.widgets = (delete_button, key_code, original_key)
+ self.widgets = (key_code, original_key, delete_button)
- def on_delete_button_clicked(self, button):
+ def on_delete_button_clicked(self, *args):
"""Destroy the row and remove it from the config."""
for widget in self.widgets:
widget.destroy()
@@ -92,7 +98,7 @@ class Window:
builder.connect_signals(self)
self.builder = builder
- window = builder.get_object('window')
+ window = self.get('window')
window.show()
self.window = window
@@ -100,6 +106,14 @@ class Window:
self.select_newest_preset()
+ css_provider = Gtk.CssProvider()
+ css_provider.load_from_path(get_data_path('style.css'))
+ Gtk.StyleContext.add_provider_for_screen(
+ Gdk.Screen.get_default(),
+ css_provider,
+ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
+ )
+
def get(self, name):
"""Get a widget from the window"""
return self.builder.get_object(name)
@@ -216,23 +230,18 @@ class Window:
self.mappings = []
# TODO show all mapped keys from config
- self.clear_mapping_table()
-
- self.on_add_key_clicked()
-
- def on_add_key_clicked(self, button=None):
- """Add a mapping to the list of mappings."""
- # TODO automatically add a line when no line is empty anymore,
- # making the add button obsolete
single_key_mapping = SingleKeyMapping(self.on_row_removed)
key_list = self.get('key_list')
- key_list.insert_row(1)
+ row = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
+ row.set_homogeneous(True)
widgets = single_key_mapping.get_widgets()
- key_list.attach(widgets[0], 0, 1, 1, 1)
- key_list.attach(widgets[1], 1, 1, 1, 1)
- key_list.attach(widgets[2], 2, 1, 1, 1)
+ row.pack_start(widgets[0], expand=True, fill=True, padding=0)
+ row.pack_start(widgets[1], expand=True, fill=True, padding=0)
+ row.pack_start(widgets[2], expand=True, fill=True, padding=0)
+ key_list.insert(row, -1)
key_list.show_all()
- self.rows += 1
+
+ self.clear_mapping_table()
def on_row_removed(self, mapping):
"""Stuff to do when a row was removed
diff --git a/data/key-mapper.glade b/data/key-mapper.glade
index 90f8abc8..879489cd 100644
--- a/data/key-mapper.glade
+++ b/data/key-mapper.glade
@@ -8,6 +8,48 @@
asdf
0.5
+
+
450
False
@@ -133,18 +175,6 @@
2
-
-
- True
- False
- 0
-
-
- True
- True
- 3
-
-
gtk-delete
@@ -272,38 +302,37 @@
- 200
True
False
vertical
-
+
True
False
- 10
+ True
- 50
True
False
- Mapping
- 0
+ 5
+ 5
+ Key
+ 10
- True
+ False
True
0
-
- gtk-add
- 80
+
True
- True
- True
- True
-
+ False
+ 5
+ 5
+ Mapping
+ 10
False
@@ -311,6 +340,17 @@
1
+
+
+ True
+ False
+
+
+ False
+ True
+ 2
+
+
False
@@ -319,46 +359,26 @@
-
+
True
False
- 10
- 10
- 10
- 2
- 2
-
-
- True
- False
- True
- Mapping
-
-
- 2
- 0
-
-
-
-
- True
- False
- True
- Key
-
-
- 1
- 0
-
-
-
-
-
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ none
True
True
- 1
+ 2
diff --git a/data/screenshot.png b/data/screenshot.png
index 25786349..3d938488 100644
Binary files a/data/screenshot.png and b/data/screenshot.png differ
diff --git a/data/style.css b/data/style.css
new file mode 100644
index 00000000..8ebd8d2f
--- /dev/null
+++ b/data/style.css
@@ -0,0 +1,5 @@
+list entry {
+ background-color: transparent;
+}
+
+/* @theme_bg_color, @theme_fg_color */
\ No newline at end of file
diff --git a/keymapper/X.py b/keymapper/X.py
index 4c1fd297..219c60ee 100644
--- a/keymapper/X.py
+++ b/keymapper/X.py
@@ -220,6 +220,8 @@ def generate_symbols_file_content(device, preset, mappings):
for code, character in mappings:
if f'<{code}>' not in keycodes:
logger.error(f'Unknown keycode <{code}> for "{character}"')
+ # continue, otherwise X would crash when loading
+ continue
xkb_symbols.append(f'key <{code}> {{ [ {character} ] }};')
if len(xkb_symbols) == 0:
logger.error('Failed to populate xkb_symbols')