diff --git a/README.md b/README.md
index 7a95c91..9149b34 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# KeyHint
**_Utility to display keyboard shortcuts or other hints based on the active window on
-Linux. (GTK 4.6+ required!)_**
+Linux._**
@@ -24,6 +24,12 @@ Linux. (GTK 4.6+ required!)_**
gobject-introspection \
libgtk-4-dev
```
+- Wayland & Gnome: The
+ [Gnome Extension "Window-Calls"](https://extensions.gnome.org/extension/4724/window-calls/)
+ is required to auto-select the cheatsheet based on the current active application.
+- Wayland & KDE: Not yet implemented.
+ [Create an issue](https://github.com/dynobo/keyhint/issues/new) if you like to have
+ this support for this setup.
## Installation
diff --git a/keyhint/resources/headerbar.ui b/keyhint/resources/headerbar.ui
index 9b7cce7..757ed7c 100644
--- a/keyhint/resources/headerbar.ui
+++ b/keyhint/resources/headerbar.ui
@@ -27,8 +27,10 @@
true
3
4
- 12
- 6
+ 14
+
Sort sections by height
@@ -84,8 +86,10 @@
true
3
4
- 12
- 6
+ 14
+
Scroll left ↔ right
@@ -123,20 +127,17 @@
-
+
Adjust font size
- 4
- 12
- 3
- 100
- 1
+ 0
+ 14
0
+ 0
- 70
- 150
- 10
100
+ 75
+ 150
@@ -150,13 +151,27 @@
-
- keyhint
+
+ 0
3
4
12
- Type cheatsheet id...
- Used if no matching cheatsheet is found
+
+
+
+ keyhint
+ false
+ Shown if no matching cheatsheet is found
+
+
+
+
+ view-pin-symbolic
+ Set to current cheatsheet
+
+
diff --git a/keyhint/window.py b/keyhint/window.py
index 670cdb1..4f9bfa3 100644
--- a/keyhint/window.py
+++ b/keyhint/window.py
@@ -39,7 +39,7 @@ def check_state(func: TActionCallback) -> TActionCallback:
"""Decorator to only execute the function if the action state changed."""
def wrapper(cls: Gtk.Widget, action: Gio.SimpleAction, state: GLib.Variant) -> None:
- if action.get_state() == state:
+ if action.get_state_type() and action.get_state() == state:
return None
if state:
@@ -69,8 +69,9 @@ class HeaderBarBox(Gtk.HeaderBar):
sheet_dropdown = cast(Gtk.DropDown, Gtk.Template.Child())
search_entry = cast(Gtk.SearchEntry, Gtk.Template.Child())
fullscreen_button = cast(Gtk.ToggleButton, Gtk.Template.Child())
- zoom_spin_button = cast(Gtk.SpinButton, Gtk.Template.Child())
+ zoom_scale = cast(Gtk.Scale, Gtk.Template.Child())
fallback_sheet_entry = cast(Gtk.Entry, Gtk.Template.Child())
+ fallback_sheet_button = cast(Gtk.Button, Gtk.Template.Child())
def __init__(
self, for_fullscreen: bool = False, decoration: str | None = None
@@ -169,7 +170,7 @@ def init_action_sort_by(self) -> None:
# Create
action = Gio.SimpleAction.new_stateful(
name="sort_by",
- state=GLib.Variant("s", "size"),
+ state=GLib.Variant("s", ""),
parameter_type=GLib.VariantType.new("s"),
)
action.connect("activate", self.on_change_sort)
@@ -188,20 +189,27 @@ def init_action_zoom(self) -> None:
# Create
action = Gio.SimpleAction.new_stateful(
name="zoom",
- state=GLib.Variant("i", 100),
+ state=GLib.Variant("i", 0),
parameter_type=GLib.VariantType.new("i"),
)
action.connect("change-state", self.on_change_zoom)
self.add_action(action)
- # Connect
+ # Connect & add marks
for headerbar in [self.headerbar, self.headerbar_fs]:
- headerbar.zoom_spin_button.connect(
+ headerbar.zoom_scale.connect(
"value-changed",
lambda btn: self.change_action_state(
- "zoom", GLib.Variant("i", btn.get_value_as_int())
+ "zoom", GLib.Variant("i", btn.get_value())
),
)
+ slider_range = headerbar.zoom_scale.get_adjustment()
+ for i in range(
+ int(slider_range.get_lower()), int(slider_range.get_upper()) + 1, 25
+ ):
+ headerbar.zoom_scale.add_mark(
+ i, Gtk.PositionType.BOTTOM, f"{i} "
+ )
# Init state
self.change_action_state(
@@ -235,7 +243,7 @@ def init_action_orientation(self) -> None:
# Create
action = Gio.SimpleAction.new_stateful(
name="orientation",
- state=GLib.Variant("s", "vertical"),
+ state=GLib.Variant("s", ""),
parameter_type=GLib.VariantType.new("s"),
)
action.connect("activate", self.on_change_orientation)
@@ -255,18 +263,19 @@ def init_action_fallback_sheet(self) -> None:
# Create
action = Gio.SimpleAction.new_stateful(
name="fallback_sheet",
- state=GLib.Variant("s", "keyhint"),
+ state=GLib.Variant("s", ""),
parameter_type=GLib.VariantType.new("s"),
)
- action.connect("change-state", self.on_change_fallback_sheet)
+ action.connect("change-state", self.on_set_fallback_sheet)
self.add_action(action)
# Connect
for headerbar in [self.headerbar, self.headerbar_fs]:
- headerbar.fallback_sheet_entry.connect(
- "changed",
- lambda entry: self.change_action_state(
- "fallback_sheet", GLib.Variant("s", entry.get_text())
+ headerbar.fallback_sheet_button.connect(
+ "clicked",
+ lambda *args: self.change_action_state(
+ "fallback_sheet",
+ GLib.Variant("s", self.get_current_sheet_id() or "keyhint"),
),
)
@@ -282,7 +291,7 @@ def init_action_sheet(self) -> None:
# Create
action = Gio.SimpleAction.new_stateful(
name="sheet",
- state=GLib.Variant("s", "keyhint"),
+ state=GLib.Variant("s", ""),
parameter_type=GLib.VariantType.new("s"),
)
action.connect("change-state", self.on_change_sheet)
@@ -351,21 +360,14 @@ def init_populate_sheet_dropdown(self) -> None:
self.headerbar_fs.sheet_dropdown.set_model(model)
@check_state
- def on_change_fallback_sheet(
+ def on_set_fallback_sheet(
self, action: Gio.SimpleAction, state: GLib.Variant
) -> None:
"""Set the default sheet to use."""
sheet_id = state.get_string()
- if sheet_id not in [s["id"] for s in self.sheets]:
- sheet_id = "keyhint"
- css_class = "error"
- else:
- css_class = ""
- self.config.set_persistent("main", "fallback_cheatsheet", sheet_id)
- self.headerbar.fallback_sheet_entry.set_text(sheet_id)
- self.headerbar_fs.fallback_sheet_entry.set_text(sheet_id)
- self.headerbar.fallback_sheet_entry.set_css_classes([css_class])
- self.headerbar_fs.fallback_sheet_entry.set_css_classes([css_class])
+ self.config.set_persistent("main", "fallback_cheatsheet", sheet_id)
+ for headerbar in [self.headerbar, self.headerbar_fs]:
+ headerbar.fallback_sheet_entry.set_text(sheet_id)
@check_state
def on_change_sheet(self, action: Gio.SimpleAction, state: GLib.Variant) -> None:
@@ -398,8 +400,8 @@ def on_change_zoom(self, action: Gio.SimpleAction, state: GLib.Variant) -> None:
font-size: {value}%;
}}
"""
- self.headerbar.zoom_spin_button.set_value(value)
- self.headerbar_fs.zoom_spin_button.set_value(value)
+ self.headerbar.zoom_scale.set_value(value)
+ self.headerbar_fs.zoom_scale.set_value(value)
if hasattr(self.zoom_css_provider, "load_from_string"):
# GTK 4.12+
self.zoom_css_provider.load_from_string(css)
@@ -773,10 +775,13 @@ def create_section(
section_child.set_child(column_view)
return section_child
- def get_debug_info_text(self) -> str:
+ def get_current_sheet_id(self) -> str:
action = self.lookup_action("sheet")
state = action.get_state() if action else None
- sheet_id = state.get_string() if state else None
+ return state.get_string() if state else ""
+
+ def get_debug_info_text(self) -> str:
+ sheet_id = self.get_current_sheet_id()
sheet = (
sheets.get_sheet_by_id(sheets=self.sheets, sheet_id=sheet_id)
if sheet_id