From d8cc34e927ea7a08b420c353165edf1c5ca57f28 Mon Sep 17 00:00:00 2001 From: djinnalexio Date: Tue, 20 Oct 2026 10:36:09 +0100 Subject: [PATCH] feat: :sparkles: add page-specific keyboard shortcuts help Ctrl+? now opens the shortcuts dialog of the visible page instead of only in the book-viewer. - add a library shortcuts overlay (app-help-overlay) and rename book viewer shortcuts overlay (book-help-overlay) - add `utils.showHelpOverlay()` to build and present an overlay by name - have the app-level `win.show-help-overlay` action and shortcut delegate to the visible page's `showHelpOverlay()`, falling back to the app overlay - the shortcut in book viewer is kept so it's visible in the UI --- po/POTFILES | 3 +- src/app.js | 12 +++- src/book-viewer.js | 13 ++-- src/gresource.xml | 4 +- src/ui/app-help-overlay.ui | 64 +++++++++++++++++++ .../{help-overlay.ui => book-help-overlay.ui} | 4 +- src/ui/book-viewer.ui | 7 +- src/ui/library.ui | 2 +- src/utils.js | 9 +++ 9 files changed, 99 insertions(+), 19 deletions(-) create mode 100644 src/ui/app-help-overlay.ui rename src/ui/{help-overlay.ui => book-help-overlay.ui} (99%) diff --git a/po/POTFILES b/po/POTFILES index 62de1cea..a12e451f 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -12,13 +12,14 @@ src/tts.js src/utils.js src/ui/annotation-popover.ui src/ui/annotation-row.ui +src/ui/app-help-overlay.ui +src/ui/book-help-overlay.ui src/ui/book-image.ui src/ui/book-item.ui src/ui/book-row.ui src/ui/book-viewer.ui src/ui/bookmark-row.ui src/ui/export-dialog.ui -src/ui/help-overlay.ui src/ui/image-viewer.ui src/ui/import-dialog.ui src/ui/library.ui diff --git a/src/app.js b/src/app.js index b4d64410..19b3e77c 100644 --- a/src/app.js +++ b/src/app.js @@ -100,8 +100,8 @@ const ApplicationWindow = GObject.registerClass({ utils.addMethods(this, { actions: [ - 'open', 'open-or-import', - 'close', 'show-library', 'show-menu', 'new-window', 'open-copy', + 'open', 'open-or-import', 'close', 'show-library', 'show-menu', + 'show-help-overlay', 'new-window', 'open-copy', ], props: ['fullscreened'], }) @@ -234,6 +234,13 @@ const ApplicationWindow = GObject.registerClass({ showMenu() { if (this.#bookViewer) this.#bookViewer.showPrimaryMenu() } + showHelpOverlay() { + const child = this.#stack.visible_child + if (typeof child?.showHelpOverlay === 'function') + return child.showHelpOverlay() + + utils.showHelpOverlay('app-help-overlay', this) + } addWindow(file) { const { application } = this const win = new ApplicationWindow({ application, file }) @@ -267,6 +274,7 @@ export const Application = GObject.registerClass({ 'win.close': ['w'], 'win.fullscreened': ['F11'], 'win.show-menu': ['F10'], + 'win.show-help-overlay': ['question'], 'win.open': ['o'], 'win.open-copy': ['n'], })) this.set_accels_for_action(key, val) diff --git a/src/book-viewer.js b/src/book-viewer.js index 27640a54..c7c9441c 100644 --- a/src/book-viewer.js +++ b/src/book-viewer.js @@ -736,7 +736,7 @@ export const BookViewer = GObject.registerClass({ actions: [ 'toggle-sidebar', 'toggle-search', 'show-location', 'toggle-toc', 'toggle-annotations', 'toggle-bookmarks', - 'preferences', 'help-overlay', 'show-info', 'bookmark', + 'preferences', 'show-help-overlay', 'show-info', 'bookmark', 'export-annotations', 'import-annotations', ], props: ['fold-sidebar'], @@ -754,7 +754,7 @@ export const BookViewer = GObject.registerClass({ 'd': 'viewer.toggle-bookmarks', 'd': 'viewer.bookmark', 'comma': 'viewer.preferences', - 'question': 'viewer.help-overlay', + 'question': 'viewer.show-help-overlay', 'g': 'search.prev', 'g': 'search.next', 'c': 'selection.copy', @@ -1060,13 +1060,8 @@ export const BookViewer = GObject.registerClass({ importAnnotations() { importAnnotations(this.root, this.#data) } - helpOverlay() { - const path = pkg.modulepath('ui/help-overlay.ui') - const builder = pkg.useResource - ? Gtk.Builder.new_from_resource(path) - : Gtk.Builder.new_from_file(path) - const dialog = builder.get_object('help-overlay') - dialog.present(this.root) + showHelpOverlay() { + utils.showHelpOverlay('book-help-overlay', this.root) } vfunc_unroot() { this._navbar.tts_box.kill() diff --git a/src/gresource.xml b/src/gresource.xml index 21cfa27b..2ba52d7b 100644 --- a/src/gresource.xml +++ b/src/gresource.xml @@ -20,13 +20,14 @@ webview.js ui/annotation-popover.ui ui/annotation-row.ui + ui/app-help-overlay.ui + ui/book-help-overlay.ui ui/book-image.ui ui/book-item.ui ui/book-row.ui ui/book-viewer.ui ui/bookmark-row.ui ui/export-dialog.ui - ui/help-overlay.ui ui/image-viewer.ui ui/import-dialog.ui ui/library-view.ui @@ -269,3 +270,4 @@ reader/reader.js + diff --git a/src/ui/app-help-overlay.ui b/src/ui/app-help-overlay.ui new file mode 100644 index 00000000..8b56f08b --- /dev/null +++ b/src/ui/app-help-overlay.ui @@ -0,0 +1,64 @@ + + + + + + Window + + + <ctrl>o + Open File + + + + + <ctrl>n + Open a Copy + + + + + F11 + Toggle Fullscreen + + + + + <ctrl>w + Close Window + + + + + <ctrl>q + Quit + + + + + + + General + + + F1 + Show App Information + + + + + F10 + Open Menu + + + + + <ctrl>question + Keyboard Shortcuts + + + + + + + diff --git a/src/ui/help-overlay.ui b/src/ui/book-help-overlay.ui similarity index 99% rename from src/ui/help-overlay.ui rename to src/ui/book-help-overlay.ui index 68565a43..1e4afbb6 100644 --- a/src/ui/help-overlay.ui +++ b/src/ui/book-help-overlay.ui @@ -1,6 +1,6 @@ - + - + Navigation diff --git a/src/ui/book-viewer.ui b/src/ui/book-viewer.ui index 91fac16c..c6250c93 100644 --- a/src/ui/book-viewer.ui +++ b/src/ui/book-viewer.ui @@ -1,4 +1,5 @@ - + +
@@ -29,7 +30,7 @@
Keyboard Shortcuts - viewer.help-overlay + viewer.show-help-overlay About Foliate @@ -264,7 +265,7 @@ True edit-find-symbolic - + Find in book… diff --git a/src/ui/library.ui b/src/ui/library.ui index 1d4e6084..109e6b29 100644 --- a/src/ui/library.ui +++ b/src/ui/library.ui @@ -33,11 +33,11 @@ Preferences app.preferences + --> Keyboard Shortcuts win.show-help-overlay - --> About Foliate app.about diff --git a/src/utils.js b/src/utils.js index f9afabea..db27902e 100644 --- a/src/utils.js +++ b/src/utils.js @@ -401,3 +401,12 @@ export const addClass = (widget, ...classes) => { for (const c of classes) widget.add_css_class(c) return widget } + +export const showHelpOverlay = (name, parent) => { + const path = pkg.modulepath(`ui/${name}.ui`) + const builder = pkg.useResource + ? Gtk.Builder.new_from_resource(path) + : Gtk.Builder.new_from_file(path) + const dialog = builder.get_object(name) + dialog.present(parent) +}