feat(ags osk): add input detection
All checks were successful
Discord / discord commits (push) Has been skipped

This commit is contained in:
matt1432 2024-12-14 19:36:54 -05:00
parent 2757906d49
commit ce6d31e658
10 changed files with 141 additions and 22 deletions

Binary file not shown.

BIN
flake.nix

Binary file not shown.

View file

@ -169,6 +169,11 @@ let
owner = "Cu3PO42"; owner = "Cu3PO42";
repo = "gtk-session-lock"; repo = "gtk-session-lock";
}; };
virtualkeyboard-adapter = mkDep {
owner = "horriblename";
repo = "fcitx-virtualkeyboard-adapter";
};
}; };
}; };

View file

@ -21,6 +21,7 @@ import Screenshot from '../widgets/screenshot/main';
import { closeAll, perMonitor } from '../lib'; import { closeAll, perMonitor } from '../lib';
import Brightness from '../services/brightness'; import Brightness from '../services/brightness';
import MonitorClicks from '../services/monitor-clicks'; import MonitorClicks from '../services/monitor-clicks';
import Tablet from '../services/tablet';
export default () => { export default () => {
@ -48,6 +49,42 @@ export default () => {
popup_osd(request.replace('popup ', '')); popup_osd(request.replace('popup ', ''));
respond('osd popped up'); respond('osd popped up');
} }
else if (request.startsWith('show-osk')) {
const tablet = Tablet.get_default();
if (tablet.currentMode === 'tablet') {
if (tablet.oskState) {
respond('osk state was unchanged');
}
else {
tablet.oskState = true;
tablet.oskAutoChanged = true;
respond('osk was shown');
}
}
else {
respond('osk state was unchanged');
}
}
else if (request.startsWith('hide-osk')) {
const tablet = Tablet.get_default();
if (tablet.currentMode === 'tablet') {
if (tablet.oskState && tablet.oskAutoChanged) {
tablet.oskState = false;
tablet.oskAutoChanged = true;
respond('osd was hidden');
}
else {
respond('osk state was unchanged');
}
}
else {
respond('osk state was unchanged');
}
}
}, },
main: () => { main: () => {

View file

@ -31,7 +31,7 @@ export default class Tablet extends GObject.Object {
declare inputsChanged: (blocked: boolean) => void; declare inputsChanged: (blocked: boolean) => void;
private _currentMode = 'laptop'; private _currentMode: 'laptop' | 'tablet' = 'laptop';
@property(String) @property(String)
get currentMode() { get currentMode() {
@ -42,18 +42,19 @@ export default class Tablet extends GObject.Object {
this._currentMode = val; this._currentMode = val;
if (this._currentMode === 'tablet') { if (this._currentMode === 'tablet') {
execAsync(['brightnessctl', '-d', 'tpacpi::kbd_backlight', 's', '0']) execAsync(['brightnessctl', '-d', 'tpacpi::kbd_backlight', 's', '0']).catch(print);
.catch(print);
this.startAutorotate(); this.startAutorotate();
this._blockInputs(); this._blockInputs();
this._startInputDetection();
} }
else if (this._currentMode === 'laptop') { else if (this._currentMode === 'laptop') {
execAsync(['brightnessctl', '-d', 'tpacpi::kbd_backlight', 's', '2']) execAsync(['brightnessctl', '-d', 'tpacpi::kbd_backlight', 's', '2']).catch(print);
.catch(print);
this.killAutorotate(); this.killAutorotate();
this._unblockInputs(); this._unblockInputs();
this._stopInputDetection();
this.oskState = false;
} }
this.notify('current-mode'); this.notify('current-mode');
@ -69,6 +70,8 @@ export default class Tablet extends GObject.Object {
set oskState(val) { set oskState(val) {
this._oskState = val; this._oskState = val;
// this is set to true after this setter in the request.
this.oskAutoChanged = false;
this.notify('osk-state'); this.notify('osk-state');
} }
@ -77,6 +80,40 @@ export default class Tablet extends GObject.Object {
} }
private _oskAutoChanged = false;
@property(Boolean)
get oskAutoChanged() {
return this._oskAutoChanged;
}
set oskAutoChanged(val) {
this._oskAutoChanged = val;
}
private _inputDetection = null as AstalIO.Process | null;
private _startInputDetection() {
if (this._inputDetection) {
return;
}
this._inputDetection = subprocess([
'fcitx5',
'--disable', 'all',
'--enable', 'keyboard,virtualkeyboardadapter,wayland,waylandim',
]);
}
private _stopInputDetection() {
if (this._inputDetection) {
this._inputDetection.kill();
this._inputDetection = null;
}
}
private _autorotate = null as AstalIO.Process | null; private _autorotate = null as AstalIO.Process | null;
get autorotateState() { get autorotateState() {

View file

@ -19,8 +19,9 @@
background-color: color.adjust(colors.$window_bg_color, $lightness: 3%); background-color: color.adjust(colors.$window_bg_color, $lightness: 3%);
} }
&.bluetooth icon,
&.network icon, &.network icon,
&.bluetooth icon { &.tablet-mode icon {
min-width: 30px; min-width: 30px;
} }

View file

@ -1,3 +1,4 @@
import { bind } from 'astal';
import { Astal, Gtk } from 'astal/gtk3'; import { Astal, Gtk } from 'astal/gtk3';
import Audio from './items/audio'; import Audio from './items/audio';
@ -13,9 +14,9 @@ import Workspaces from './items/workspaces';
import BarRevealer from './fullscreen'; import BarRevealer from './fullscreen';
import Separator from '../misc/separator'; import Separator from '../misc/separator';
import Tablet from '../../services/tablet';
// TODO: add Bluetooth
export default () => ( export default () => (
<BarRevealer <BarRevealer
exclusivity={Astal.Exclusivity.EXCLUSIVE} exclusivity={Astal.Exclusivity.EXCLUSIVE}
@ -33,7 +34,23 @@ export default () => (
<SysTray /> <SysTray />
{/* <Separator size={8} /> */} <Separator size={8} />
<button
className="bar-item tablet-mode"
cursor="pointer"
onButtonReleaseEvent={() => {
const tablet = Tablet.get_default();
tablet.toggleMode();
}}
>
<icon
icon={bind(Tablet.get_default(), 'currentMode')
.as((mode) => `${mode}-symbolic`)}
/>
</button>
<CurrentClient /> <CurrentClient />

View file

@ -1,8 +1,10 @@
self: { self: {
config, config,
lib, lib,
pkgs,
... ...
}: let }: let
inherit (self.inputs) virtualkeyboard-adapter;
inherit (lib) hasPrefix mkIf removePrefix; inherit (lib) hasPrefix mkIf removePrefix;
# Configs # Configs
@ -50,6 +52,19 @@ in {
security.pam.services.astal-auth = {}; security.pam.services.astal-auth = {};
services.upower.enable = true; services.upower.enable = true;
i18n.inputMethod = mkIf cfgDesktop.isTouchscreen {
enable = true;
type = "fcitx5";
fcitx5 = {
waylandFrontend = true;
plasma6Support = true;
addons = [
virtualkeyboard-adapter.packages.${pkgs.system}.default
];
};
};
home-manager.users.${cfgDesktop.user}.imports = [ home-manager.users.${cfgDesktop.user}.imports = [
hmOpts hmOpts
(import ./packages.nix self) (import ./packages.nix self)

View file

@ -1,5 +1,4 @@
self: {lib, ...}: let self: {...}: let
inherit (lib) map;
inherit (self.lib.hypr) mkAnimation mkBezier mkBind mkLayerRule; inherit (self.lib.hypr) mkAnimation mkBezier mkBind mkLayerRule;
in { in {
config.wayland.windowManager.hyprland = { config.wayland.windowManager.hyprland = {

View file

@ -7,12 +7,24 @@ self: {
}: let }: let
inherit (self.inputs) ags gtk-session-lock; inherit (self.inputs) ags gtk-session-lock;
inherit (lib) attrValues boolToString optionals removeAttrs; inherit (lib) attrValues boolToString getExe optionalAttrs optionals removeAttrs;
inherit (osConfig.networking) hostName; inherit (osConfig.networking) hostName;
cfg = config.programs.ags; cfg = config.programs.ags;
cfgDesktop = osConfig.roles.desktop; cfgDesktop = osConfig.roles.desktop;
mainPkg = pkgs.writeShellApplication {
name = "ags";
runtimeInputs = [cfg.package];
text = ''
if [ "$#" == 0 ]; then
exec ags run ~/${cfg.configDir} -a ${hostName}
else
exec ags "$@"
fi
'';
};
in { in {
config = { config = {
# Make these accessible outside these files # Make these accessible outside these files
@ -50,17 +62,7 @@ in {
home = { home = {
packages = packages =
[ [
(pkgs.writeShellApplication { mainPkg
name = "ags";
runtimeInputs = [cfg.package];
text = ''
if [ "$#" == 0 ]; then
exec ags run ~/${cfg.configDir} -a ${hostName}
else
exec ags "$@"
fi
'';
})
(pkgs.writeShellApplication { (pkgs.writeShellApplication {
name = "agsConf"; name = "agsConf";
runtimeInputs = [cfg.package]; runtimeInputs = [cfg.package];
@ -131,6 +133,12 @@ in {
}; };
''; '';
} }
// optionalAttrs cfgDesktop.isTouchscreen {
".config/fcitx5/conf/virtualkeyboardadapter.conf".text = ''
ActivateCmd="${getExe mainPkg} request 'show-osk'"
DeactivateCmd="${getExe mainPkg} request 'hide-osk'"
'';
}
); );
}; };
}; };