From a98ca53dfb9e3f1e6b32bbb3becce88d321384ba Mon Sep 17 00:00:00 2001 From: Rafostar <40623528+Rafostar@users.noreply.github.com> Date: Sun, 25 Apr 2021 20:19:44 +0200 Subject: [PATCH] Use Gio.SimpleAction as only keypress handler --- src/actions.js | 112 +++++++++++++++++++++++++++++++------------ src/appBase.js | 13 ++--- src/buttons.js | 6 --- src/controls.js | 30 ------------ src/headerbarBase.js | 6 ++- src/player.js | 78 +----------------------------- src/widget.js | 48 +++++++++++-------- 7 files changed, 123 insertions(+), 170 deletions(-) diff --git a/src/actions.js b/src/actions.js index b9afd3cf..87721d4e 100644 --- a/src/actions.js +++ b/src/actions.js @@ -1,34 +1,86 @@ const Dialogs = imports.src.dialogs; var actions = { - open_local: { - run: (window) => new Dialogs.FileChooser(window), - accels: ['O'], - }, - open_uri: { - run: (window) => new Dialogs.UriDialog(window), - accels: ['U'], - }, - prefs: { - run: (window) => new Dialogs.PrefsDialog(window), - }, - about: { - run: (window) => new Dialogs.AboutDialog(window), - }, - next_track: { - run: (window) => window.child.player.playlistWidget.nextTrack(), - accels: ['Right'], - }, - prev_track: { - run: (window) => window.child.player.playlistWidget.prevTrack(), - accels: ['Left'], - }, - next_chapter: { - run: (window) => window.child.player.next_chapter(), - accels: ['Right'], - }, - prev_chapter: { - run: (window) => window.child.player.prev_chapter(), - accels: ['Left'], - } + open_local: ['O'], + open_uri: ['U'], + prefs: null, + about: null, + progress_forward: ['Right'], + progress_backward: ['Left'], + next_chapter: ['Right'], + prev_chapter: ['Left'], + next_track: ['Right'], + prev_track: ['Left'], + volume_up: ['Up'], + volume_down: ['Down'], + toggle_play: ['space'], + reveal_controls: ['Return'], + toggle_fullscreen: ['F11', 'f'], + quit: ['q', 'q'], }; + +function handleAction(action, window) +{ + const clapperWidget = window.child; + if(!clapperWidget) return; + + const { player } = clapperWidget; + let bool = false; + + switch(action.name) { + case 'open_local': + new Dialogs.FileChooser(window); + break; + case 'open_uri': + new Dialogs.UriDialog(window); + break; + case 'prefs': + new Dialogs.PrefsDialog(window); + break; + case 'about': + new Dialogs.AboutDialog(window); + break; + case 'progress_forward': + bool = true; + case 'progress_backward': + player.adjust_position(bool); + if( + clapperWidget.isReleaseKeyEnabled + && clapperWidget.isFullscreenMode + ) + clapperWidget.revealControls(); + /* Actual seek is handled on release */ + clapperWidget.isReleaseKeyEnabled = true; + if(!clapperWidget.has_focus) + clapperWidget.grab_focus(); + break; + case 'volume_up': + bool = true; + case 'volume_down': + player.adjust_volume(bool); + break; + case 'next_track': + player.playlistWidget.nextTrack(); + break; + case 'prev_track': + player.playlistWidget.prevTrack(); + break; + case 'reveal_controls': + if(clapperWidget.isFullscreenMode) + clapperWidget.revealControls(); + break; + case 'toggle_fullscreen': + clapperWidget.toggleFullscreen(); + break; + case 'quit': + clapperWidget.root.emit('close-request'); + break; + case 'toggle_play': + case 'next_chapter': + case 'prev_chapter': + player[action.name](); + break; + default: + break; + } +} diff --git a/src/appBase.js b/src/appBase.js index 8e237e84..aaede1e8 100644 --- a/src/appBase.js +++ b/src/appBase.js @@ -2,7 +2,7 @@ const { Gio, GLib, GObject, Gtk } = imports.gi; const Debug = imports.src.debug; const FileOps = imports.src.fileOps; const Misc = imports.src.misc; -const { actions } = imports.src.actions; +const Actions = imports.src.actions; const { debug } = Debug; const { settings } = Misc; @@ -35,15 +35,16 @@ class ClapperAppBase extends Gtk.Application if(!settings.get_boolean('render-shadows')) window.add_css_class('gpufriendly'); - for(let name in actions) { + for(let name in Actions.actions) { const simpleAction = new Gio.SimpleAction({ name }); - simpleAction.connect( - 'activate', () => actions[name].run(this.active_window) + simpleAction.connect('activate', (action) => + Actions.handleAction(action, this.active_window) ); this.add_action(simpleAction); - if(actions[name].accels) - this.set_accels_for_action(`app.${name}`, actions[name].accels); + const accels = Actions.actions[name]; + if(accels) + this.set_accels_for_action(`app.${name}`, accels); } } diff --git a/src/buttons.js b/src/buttons.js index fb0ba4e9..fdc11c20 100644 --- a/src/buttons.js +++ b/src/buttons.js @@ -31,8 +31,6 @@ class ClapperCustomButton extends Gtk.Button if(this.isFullscreen === isFullscreen) return; - this.can_focus = isFullscreen; - /* Redraw icon after style class change */ if(this.icon_name) this.set_icon_name(this.icon_name); @@ -110,8 +108,6 @@ class ClapperPopoverButtonBase extends Gtk.ToggleButton if(this.isFullscreen === isFullscreen) return; - this.can_focus = isFullscreen; - /* Redraw icon after style class change */ if(this.icon_name) this.set_icon_name(this.icon_name); @@ -152,8 +148,6 @@ class ClapperPopoverButtonBase extends Gtk.ToggleButton { const clapperWidget = this.get_ancestor(Gtk.Grid); - clapperWidget.player.widget.grab_focus(); - /* Set again timeout as popover is now closed */ if(clapperWidget.isFullscreenMode) clapperWidget.revealControls(); diff --git a/src/controls.js b/src/controls.js index 1e58baec..63cd4309 100644 --- a/src/controls.js +++ b/src/controls.js @@ -85,11 +85,6 @@ class ClapperControls extends Gtk.Box this.unfullscreenButton.connect('clicked', this._onUnfullscreenClicked.bind(this)); this.unfullscreenButton.set_visible(false); - const keyController = new Gtk.EventControllerKey(); - keyController.connect('key-pressed', this._onControlsKeyPressed.bind(this)); - keyController.connect('key-released', this._onControlsKeyReleased.bind(this)); - this.add_controller(keyController); - this.add_css_class('playercontrols'); this.realizeSignal = this.connect('realize', this._onRealize.bind(this)); } @@ -103,8 +98,6 @@ class ClapperControls extends Gtk.Box button.setFullscreenMode(isFullscreen); this.unfullscreenButton.visible = isFullscreen; - this.can_focus = isFullscreen; - this.isFullscreen = isFullscreen; } @@ -621,29 +614,6 @@ class ClapperControls extends Gtk.Box } } - /* Only happens when navigating through controls panel */ - _onControlsKeyPressed(controller, keyval, keycode, state) - { - const clapperWidget = this.get_ancestor(Gtk.Grid); - clapperWidget._setHideControlsTimeout(); - } - - _onControlsKeyReleased(controller, keyval, keycode, state) - { - switch(keyval) { - case Gdk.KEY_space: - case Gdk.KEY_Return: - case Gdk.KEY_Escape: - case Gdk.KEY_Right: - case Gdk.KEY_Left: - break; - default: - const { player } = this.get_ancestor(Gtk.Grid); - player._onWidgetKeyReleased(controller, keyval, keycode, state); - break; - } - } - _onCloseRequest() { debug('controls close request'); diff --git a/src/headerbarBase.js b/src/headerbarBase.js index f2348259..c7982474 100644 --- a/src/headerbarBase.js +++ b/src/headerbarBase.js @@ -37,6 +37,7 @@ class ClapperHeaderBarBase extends Gtk.Box this.menuButton = new Gtk.MenuButton({ icon_name: 'open-menu-symbolic', valign: Gtk.Align.CENTER, + can_focus: false, }); const mainMenuModel = uiBuilder.get_object('mainMenu'); const mainMenuPopover = new HeaderBarPopover(mainMenuModel); @@ -53,6 +54,7 @@ class ClapperHeaderBarBase extends Gtk.Box const floatButton = new Gtk.Button({ icon_name: 'go-bottom-symbolic', + can_focus: false, }); floatButton.add_css_class('circular'); floatButton.add_css_class('linkedleft'); @@ -69,6 +71,7 @@ class ClapperHeaderBarBase extends Gtk.Box const fullscreenButton = new Gtk.Button({ icon_name: 'view-fullscreen-symbolic', + can_focus: false, }); fullscreenButton.add_css_class('circular'); fullscreenButton.add_css_class('linkedright'); @@ -196,6 +199,7 @@ class ClapperHeaderBarBase extends Gtk.Box const button = new Gtk.Button({ icon_name: `window-${name}-symbolic`, valign: Gtk.Align.CENTER, + can_focus: false, }); button.add_css_class('circular'); @@ -263,7 +267,5 @@ class ClapperHeaderBarPopover extends Gtk.PopoverMenu child.revealControls(); child.isPopoverOpen = false; - - child.player.widget.grab_focus(); } }); diff --git a/src/player.js b/src/player.js index 17b13e37..f447a120 100644 --- a/src/player.js +++ b/src/player.js @@ -38,6 +38,7 @@ class ClapperPlayer extends GstClapper.Clapper this.webserver = null; this.webapp = null; + this.ytClient = null; this.playlistWidget = new PlaylistWidget(); this.seek_done = true; @@ -50,14 +51,6 @@ class ClapperPlayer extends GstClapper.Clapper this.quitOnStop = false; this.needsTocUpdate = true; - this.keyPressCount = 0; - this.ytClient = null; - - const keyController = new Gtk.EventControllerKey(); - keyController.connect('key-pressed', this._onWidgetKeyPressed.bind(this)); - keyController.connect('key-released', this._onWidgetKeyReleased.bind(this)); - this.widget.add_controller(keyController); - this.set_all_plugins_ranks(); this.set_initial_config(); this.set_and_bind_settings(); @@ -638,75 +631,6 @@ class ClapperPlayer extends GstClapper.Clapper ); } - /* Widget only - does not happen when using controls navigation */ - _onWidgetKeyPressed(controller, keyval, keycode, state) - { - const clapperWidget = this.widget.get_ancestor(Gtk.Grid); - let bool = false; - - switch(keyval) { - case Gdk.KEY_Up: - bool = true; - case Gdk.KEY_Down: - this.adjust_volume(bool); - break; - case Gdk.KEY_Right: - bool = true; - case Gdk.KEY_Left: - this.adjust_position(bool); - if(this.keyPressCount > 1) - clapperWidget.revealControls(); - break; - case Gdk.KEY_space: - this.toggle_play(); - break; - case Gdk.KEY_Return: - if(clapperWidget.isFullscreenMode) - clapperWidget.revealControls(true); - break; - case Gdk.KEY_F11: - case Gdk.KEY_f: - case Gdk.KEY_F: - clapperWidget.toggleFullscreen(); - break; - case Gdk.KEY_q: - case Gdk.KEY_Q: - this.widget.root.emit('close-request'); - break; - default: - return; - } - - this.keyPressCount++; - } - - /* Also happens after using controls navigation for selected keys */ - _onWidgetKeyReleased(controller, keyval, keycode, state) - { - /* Ignore releases that did not trigger keypress - * e.g. while holding left "Super" key */ - if(!this.keyPressCount) - return; - - const clapperWidget = this.widget.get_ancestor(Gtk.Grid); - let value; - - this.keyPressCount = 0; - - switch(keyval) { - case Gdk.KEY_Right: - case Gdk.KEY_Left: - value = Math.round( - clapperWidget.controls.positionScale.get_value() - ); - this.seek_seconds(value); - clapperWidget._setHideControlsTimeout(); - break; - default: - break; - } - } - _onWindowMap(window) { this.windowMapped = true; diff --git a/src/widget.js b/src/widget.js index 9b22a460..73831cd6 100644 --- a/src/widget.js +++ b/src/widget.js @@ -31,6 +31,7 @@ class ClapperWidget extends Gtk.Grid this.isDragAllowed = false; this.isSwipePerformed = false; + this.isReleaseKeyEnabled = false; this.isCursorInPlayer = false; this.isPopoverOpen = false; @@ -103,18 +104,20 @@ class ClapperWidget extends Gtk.Grid const dropTarget = this._getDropTarget(); playerWidget.add_controller(dropTarget); + + /* Applied only for widget to detect simple action key releases */ + const keyController = new Gtk.EventControllerKey(); + keyController.connect('key-released', this._onKeyReleased.bind(this)); + this.add_controller(keyController); } - revealControls(isAllowInput) + revealControls() { this.revealerTop.revealChild(true); this.revealerBottom.revealChild(true); this._checkSetUpdateTimeInterval(); - if(isAllowInput) - this.setControlsCanFocus(true); - /* Reset timeout if already revealed, otherwise * timeout will be set after reveal finishes */ if(this.revealerTop.child_revealed) @@ -157,8 +160,6 @@ class ClapperWidget extends Gtk.Grid if(this.revealerTop.child_revealed) this._checkSetUpdateTimeInterval(); - this.setControlsCanFocus(false); - if(this.player.playOnFullscreen && isFullscreen) { this.player.playOnFullscreen = false; this.player.play(); @@ -167,18 +168,6 @@ class ClapperWidget extends Gtk.Grid debug(`interface in fullscreen mode: ${isFullscreen}`); } - setControlsCanFocus(isControlsFocus) - { - this.revealerBottom.can_focus = isControlsFocus; - this.player.widget.can_focus = !isControlsFocus; - - const focusWidget = (isControlsFocus) - ? this.controls.togglePlayButton - : this.player.widget; - - focusWidget.grab_focus(); - } - _changeControlsPlacement(isOnTop) { if(isOnTop) { @@ -619,7 +608,6 @@ class ClapperWidget extends Gtk.Grid this.revealerTop.revealChild(false); this.revealerBottom.revealChild(false); } - this.setControlsCanFocus(false); return GLib.SOURCE_REMOVE; }); @@ -767,6 +755,28 @@ class ClapperWidget extends Gtk.Grid } } + _onKeyReleased(controller, keyval, keycode, state) + { + /* Ignore releases that did not trigger keypress + * e.g. while holding left "Super" key */ + if(!this.isReleaseKeyEnabled) + return; + + switch(keyval) { + case Gdk.KEY_Right: + case Gdk.KEY_Left: + const value = Math.round( + this.controls.positionScale.get_value() + ); + this.player.seek_seconds(value); + this._setHideControlsTimeout(); + this.isReleaseKeyEnabled = false; + break; + default: + break; + } + } + _onDragUpdate(gesture, offsetX, offsetY) { if(!this.isDragAllowed || this.isFullscreenMode)