puavo-org / puavo-os

Puavo OS is an disk image based operating system that is built from Debian GNU/Linux and is specifically designed for learning.
https://puavo.org
GNU General Public License v2.0
13 stars 7 forks source link

Disable the screen keyboard if a real keyboard exists #707

Closed tuomasjjrasanen closed 2 months ago

tuomasjjrasanen commented 5 months ago

This PR introduces a new GNOME Shell Extension: screenkeyboardcontroller@puavo.org, which hooks into KeyboardManager and enables/disables screen keyboard in touch mode based on the existence of a real keyboard.

If the device has a real keyboard, screen keyboard is disabled, and vice versa.

In addition, whenever input device setup is changed (Clutter's deviced-added or device-removed signal), _syncEnabled() is called to update KeyboardManager's knowledge of it's surroundings.

The relevant code section in KeyboardManager (js/ui/keyboard.js of gnome-shell):

    _lastDeviceIsTouchscreen() {
        if (!this._lastDevice)
            return false;

        let deviceType = this._lastDevice.get_device_type();
        return deviceType == Clutter.InputDeviceType.TOUCHSCREEN_DEVICE;
    }

    _syncEnabled() {
        let enableKeyboard = this._a11yApplicationsSettings.get_boolean(SHOW_KEYBOARD);
        let autoEnabled = this._seat.get_touch_mode() && this._lastDeviceIsTouchscreen();
        let enabled = enableKeyboard || autoEnabled;

        if (!enabled && !this._keyboard)
            return;

        if (enabled && !this._keyboard) {
            this._keyboard = new Keyboard();
            this._keyboard.connect('visibility-changed', () => {
                this.emit('visibility-changed');
                this._bottomDragAction.enabled = !this._keyboard.visible;
            });
        } else if (!enabled && this._keyboard) {
            this._keyboard.setCursorLocation(null);
            this._keyboard.destroy();
            this._keyboard = null;
            this._bottomDragAction.enabled = true;
        }
    }

So, whenever _syncEnabled() is called (it's a callback of multiple different signals) in "touch mode", our hook function gets to say the last word (except when screen keyboard is enabled from GSettings permanently, but that's a good thing).

has-real-keyboard just reads /proc/bus/input/devices and checks whether there's a real keyboard or not; real keyboards are connected to physical bus and have sysrq handlers. If we ever encounter a keyboard which does not fulfill this real requirement, I'm sure we can come up with more complex logic. But currently, reality looks simple, so let's assume it also is simple.

Closes #692

Mazhoon commented 5 months ago

Tested with a surface without keyboard: no extension, os-keyboard pops up, good. enable extension, os-keyboard pop ups, good. connect bluetooth keyboard, os-keyboard does not pop up, good. disconnect bluetooth keyboard, os-keyboard won't pop up (as last keyboard device was a physical keyboard?). tried tapping, opening menus etc. only after pressing power button, the os-keyboard would pop up again (as power button was considered a not-real keyboard device, I assume)

tuomasjjrasanen commented 5 months ago

connect bluetooth keyboard, os-keyboard does not pop up, good. disconnect bluetooth keyboard, os-keyboard won't pop up (as last keyboard device was a physical keyboard?). tried tapping, opening menus etc. only after pressing power button, the os-keyboard would pop up again (as power button was considered a not-real keyboard device, I assume)

This has been fixed now, but connecting to device-added and device-removed signals: whenever the input device setup changes, _syncEnabled() is called (which is KeyboardManager's function for deducing whether the keyboard should be enabled or not). And because we have replaced _lastDeviceIsTouchscreen(), which is called be _syncEnabled(), screen keyboard will pop up in those situations (because no hw keyboard is available).

tuomasjjrasanen commented 5 months ago

Updated the description.

tuomasjjrasanen commented 5 months ago

@juhaerk Integration from puavo-conf puavo.screenkeyboard.controller.mode to dconf key org.gnome.shell.extensions.screenkeyboardcontroller.mode is left to you.

tuomasjjrasanen commented 5 months ago

@juhaerk And now mangling from puavo-conf to dconf is done

Mazhoon commented 5 months ago

connect bluetooth keyboard, os-keyboard does not pop up, good. disconnect bluetooth keyboard, os-keyboard won't pop up (as last keyboard device was a physical keyboard?). tried tapping, opening menus etc. only after pressing power button, the os-keyboard would pop up again (as power button was considered a not-real keyboard device, I assume)

This has been fixed now, but connecting to device-added and device-removed signals: whenever the input device setup changes, _syncEnabled() is called (which is KeyboardManager's function for deducing whether the keyboard should be enabled or not). And because we have replaced _lastDeviceIsTouchscreen(), which is called be _syncEnabled(), screen keyboard will pop up in those situations (because no hw keyboard is available).

confirmed to work with bluetooth keyboard now: as soon as the system realizes bt kb is turned off, onscreen keyboard pops up -> ok