refactor(ags): remove unneeded agsV1 stuff
All checks were successful
Discord / discord commits (push) Has been skipped
All checks were successful
Discord / discord commits (push) Has been skipped
This commit is contained in:
parent
c20ec51142
commit
ab8bb48feb
137 changed files with 184 additions and 8950 deletions
|
@ -1,12 +1,12 @@
|
||||||
# My NixOS configs
|
# My NixOS configs
|
||||||
|
|
||||||
## Ags
|
## AGS
|
||||||
|
|
||||||
You might find it weird that most of my config is written in TypeScript.
|
You might find it weird that most of my config is written in TypeScript.
|
||||||
That's because all my desktops run
|
That's because all my desktops run
|
||||||
[AGS](https://github.com/Aylur/ags)
|
[AGSv2](https://github.com/Aylur/ags/tree/v2)
|
||||||
for UI. Click on
|
for UI. Click on
|
||||||
[this](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/nixosModules/ags)
|
[this](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/nixosModules/ags-v2)
|
||||||
to see my configuration.
|
to see my configuration.
|
||||||
|
|
||||||
I'm also a victim of Stockholm syndrome at this point and make my scripts
|
I'm also a victim of Stockholm syndrome at this point and make my scripts
|
||||||
|
|
|
@ -35,6 +35,5 @@ in {
|
||||||
sudo.text = mkDefault (mkBefore grosshackConf);
|
sudo.text = mkDefault (mkBefore grosshackConf);
|
||||||
login.text = mkDefault (mkBefore grosshackConf);
|
login.text = mkDefault (mkBefore grosshackConf);
|
||||||
polkit-1.text = mkDefault (mkBefore grosshackConf);
|
polkit-1.text = mkDefault (mkBefore grosshackConf);
|
||||||
ags.text = mkDefault (mkBefore grosshackConf);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
BIN
flake.lock
BIN
flake.lock
Binary file not shown.
BIN
flake.nix
BIN
flake.nix
Binary file not shown.
|
@ -156,11 +156,6 @@ let
|
||||||
};
|
};
|
||||||
|
|
||||||
agsInputs = {
|
agsInputs = {
|
||||||
ags = mkDep {
|
|
||||||
owner = "Aylur";
|
|
||||||
repo = "ags";
|
|
||||||
};
|
|
||||||
|
|
||||||
agsV2 = mkDep {
|
agsV2 = mkDep {
|
||||||
owner = "Aylur";
|
owner = "Aylur";
|
||||||
repo = "ags";
|
repo = "ags";
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
}) {};
|
}) {};
|
||||||
in "${pkg}/lib/node_modules/${pkg.pname}/node_modules";
|
in "${pkg}/lib/node_modules/${pkg.pname}/node_modules";
|
||||||
|
|
||||||
buildNodeTypes = {
|
buildGirTypes = {
|
||||||
configPath,
|
configPath,
|
||||||
packages,
|
packages,
|
||||||
pname,
|
pname,
|
||||||
|
|
|
@ -6,44 +6,55 @@
|
||||||
osConfig,
|
osConfig,
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}: {
|
}: let
|
||||||
options.programs.ags-v2.lockPkg = lib.mkOption {
|
# Inputs
|
||||||
type = with lib.types; nullOr package;
|
inherit (self.inputs) agsV2 gtk-session-lock;
|
||||||
default = null;
|
|
||||||
|
# Libs
|
||||||
|
inherit (lib) attrValues boolToString optionals removeAttrs;
|
||||||
|
|
||||||
|
# Cfg info
|
||||||
|
inherit (osConfig.networking) hostName;
|
||||||
|
cfgDesktop = osConfig.roles.desktop;
|
||||||
|
fullConfPath = "/home/${cfgDesktop.user}/${agsConfigDir}";
|
||||||
|
|
||||||
|
# Astal libraries
|
||||||
|
gtkSessionLock = gtk-session-lock.packages.${pkgs.system}.default;
|
||||||
|
agsV2Packages = agsV2.packages.${pkgs.system};
|
||||||
|
astalLibs = attrValues (removeAttrs agsV2.inputs.astal.packages.${pkgs.system} ["docs" "gjs"]) ++ [gtkSessionLock];
|
||||||
|
|
||||||
|
# Final ags package
|
||||||
|
agsFull = agsV2Packages.ags.override {extraPackages = astalLibs;};
|
||||||
|
in {
|
||||||
|
options.programs.ags-v2 = {
|
||||||
|
package = lib.mkOption {
|
||||||
|
type = with lib.types; nullOr package;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
lockPkg = lib.mkOption {
|
||||||
|
type = with lib.types; nullOr package;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = let
|
config = {
|
||||||
# Inputs
|
# Make these accessible outside these files
|
||||||
inherit (self.inputs) agsV2 gtk-session-lock;
|
programs.ags-v2 = {
|
||||||
|
package = agsFull;
|
||||||
|
|
||||||
# Libs
|
lockPkg = pkgs.writeShellApplication {
|
||||||
inherit (lib) attrValues boolToString optionals removeAttrs;
|
name = "lock";
|
||||||
|
runtimeInputs = [agsFull];
|
||||||
|
text = ''
|
||||||
|
export CONF="lock"
|
||||||
|
|
||||||
# Cfg info
|
if [ "$#" == 0 ]; then
|
||||||
inherit (osConfig.networking) hostName;
|
exec ags run ${fullConfPath}
|
||||||
cfgDesktop = osConfig.roles.desktop;
|
else
|
||||||
fullConfPath = "/home/${cfgDesktop.user}/${agsConfigDir}";
|
exec ags "$@" -i lock
|
||||||
|
fi
|
||||||
# Astal libraries
|
'';
|
||||||
gtkSessionLock = gtk-session-lock.packages.${pkgs.system}.default;
|
};
|
||||||
agsV2Packages = agsV2.packages.${pkgs.system};
|
|
||||||
astalLibs = attrValues (removeAttrs agsV2.inputs.astal.packages.${pkgs.system} ["docs" "gjs"]) ++ [gtkSessionLock];
|
|
||||||
|
|
||||||
# Final ags package
|
|
||||||
agsFull = agsV2Packages.ags.override {extraPackages = astalLibs;};
|
|
||||||
in {
|
|
||||||
programs.ags-v2.lockPkg = pkgs.writeShellApplication {
|
|
||||||
name = "lock";
|
|
||||||
runtimeInputs = [agsFull];
|
|
||||||
text = ''
|
|
||||||
export CONF="lock"
|
|
||||||
|
|
||||||
if [ "$#" == 0 ]; then
|
|
||||||
exec ags run ${fullConfPath}
|
|
||||||
else
|
|
||||||
exec ags "$@" -i lock
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
home = {
|
home = {
|
||||||
|
@ -89,10 +100,10 @@
|
||||||
inherit
|
inherit
|
||||||
(import "${self}/lib" {inherit pkgs self;})
|
(import "${self}/lib" {inherit pkgs self;})
|
||||||
buildNodeModules
|
buildNodeModules
|
||||||
buildNodeTypes
|
buildGirTypes
|
||||||
;
|
;
|
||||||
in (
|
in (
|
||||||
(buildNodeTypes {
|
(buildGirTypes {
|
||||||
pname = "agsV2";
|
pname = "agsV2";
|
||||||
configPath = "${agsConfigDir}/@girs";
|
configPath = "${agsConfigDir}/@girs";
|
||||||
packages = astalLibs;
|
packages = astalLibs;
|
||||||
|
|
1
nixosModules/ags-v2/v1/README.md
Normal file
1
nixosModules/ags-v2/v1/README.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# Moving to [AGSv2](https://github.com/Aylur/ags/tree/v2)
|
78
nixosModules/ags-v2/v1/config/global-types.d.ts
vendored
Normal file
78
nixosModules/ags-v2/v1/config/global-types.d.ts
vendored
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
// For ./ts/bar/hovers/keyboard.ts
|
||||||
|
export interface Keyboard {
|
||||||
|
address: string
|
||||||
|
name: string
|
||||||
|
rules: string
|
||||||
|
model: string
|
||||||
|
layout: string
|
||||||
|
variant: string
|
||||||
|
options: string
|
||||||
|
active_keymap: string
|
||||||
|
main: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
// For ./ts/media-player/gesture.ts
|
||||||
|
export interface Gesture {
|
||||||
|
attribute?: object
|
||||||
|
setup?(self: OverlayGeneric): void
|
||||||
|
props?: OverlayProps<unknown & Widget, unknown>
|
||||||
|
}
|
||||||
|
|
||||||
|
// For ./ts/media-player/mpris.ts
|
||||||
|
type PlayerDragProps = unknown & { dragging: boolean };
|
||||||
|
export type PlayerDrag = AgsCenterBox<
|
||||||
|
unknown & Widget, unknown & Widget, unknown & Widget, unknown & PlayerDragProps
|
||||||
|
>;
|
||||||
|
interface Colors {
|
||||||
|
imageAccent: string
|
||||||
|
buttonAccent: string
|
||||||
|
buttonText: string
|
||||||
|
hoverAccent: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// For ./ts/media-player
|
||||||
|
export interface PlayerBoxProps {
|
||||||
|
bgStyle: string
|
||||||
|
player: MprisPlayer
|
||||||
|
}
|
||||||
|
export type PlayerBox = AgsCenterBox<
|
||||||
|
unknown & Widget, unknown & Widget, unknown & Widget, PlayerBoxProps
|
||||||
|
>;
|
||||||
|
export type PlayerOverlay = AgsOverlay<AgsWidget, {
|
||||||
|
players: Map
|
||||||
|
setup: boolean
|
||||||
|
dragging: boolean
|
||||||
|
includesWidget(playerW: PlayerBox): PlayerBox
|
||||||
|
showTopOnly(): void
|
||||||
|
moveToTop(player: PlayerBox): void
|
||||||
|
}>;
|
||||||
|
export interface PlayerButtonType {
|
||||||
|
player: MprisPlayer
|
||||||
|
colors: Var<Colors>
|
||||||
|
children: StackProps['children']
|
||||||
|
onClick: string
|
||||||
|
prop: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// For ./ts/on-screen-keyboard
|
||||||
|
export type OskWindow = Window<BoxGeneric, {
|
||||||
|
startY: null | number
|
||||||
|
setVisible: (state: boolean) => void
|
||||||
|
killGestureSigs: () => void
|
||||||
|
setSlideUp: () => void
|
||||||
|
setSlideDown: () => void
|
||||||
|
}>;
|
||||||
|
|
||||||
|
// For ./ts/quick-settings
|
||||||
|
import { BluetoothDevice as BTDev } from 'types/service/bluetooth.ts';
|
||||||
|
export interface APType {
|
||||||
|
bssid: string
|
||||||
|
address: string
|
||||||
|
lastSeen: number
|
||||||
|
ssid: string
|
||||||
|
active: boolean
|
||||||
|
strength: number
|
||||||
|
iconName: string
|
||||||
|
}
|
||||||
|
export type APBox = AgsBox<unknown & Widget, { ap: Var<APType> }>;
|
||||||
|
export type DeviceBox = AgsBox<unknown & Widget, { dev: BTDev }>;
|
|
@ -1,40 +0,0 @@
|
||||||
# [AGS](https://github.com/Aylur/ags)
|
|
||||||
|
|
||||||
## Nix
|
|
||||||
|
|
||||||
This directory is the Nix entrypoint to my AGS configration.
|
|
||||||
|
|
||||||
On system activation, if this module is imported, it will
|
|
||||||
generate the `config.js` of the host with the host's name
|
|
||||||
as the parameter in `transpileTypeScript` to support a different
|
|
||||||
setup per device.
|
|
||||||
|
|
||||||
## Non-Nix
|
|
||||||
|
|
||||||
To use this setup without Nix:
|
|
||||||
|
|
||||||
```js
|
|
||||||
/* ~/.config/ags/config.js */
|
|
||||||
|
|
||||||
import { transpileTypeScript } from './js/utils.js';
|
|
||||||
|
|
||||||
export default (await transpileTypeScript('wim')).default;
|
|
||||||
```
|
|
||||||
|
|
||||||
If you want to try my main config, this is what you need to have
|
|
||||||
as your `config.js` after copying the contents of `./config` to
|
|
||||||
`~/.config/ags`
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
The main dependencies to try it are as follows:
|
|
||||||
|
|
||||||
- **bun** to transpile TS to JS
|
|
||||||
- **dart-sass** to compile SCSS to CSS
|
|
||||||
- **[coloryou](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/common/pkgs/coloryou)** for media player colors
|
|
||||||
- **playerctl** for media player functionality
|
|
||||||
|
|
||||||
If you're interested in my 2-1 laptop setup, you'll need:
|
|
||||||
|
|
||||||
- **ydotool** for my custom on-screen keyboard
|
|
||||||
- **lisgd** to have touch screen gestures
|
|
|
@ -1,19 +0,0 @@
|
||||||
{
|
|
||||||
cliphist,
|
|
||||||
gawk,
|
|
||||||
imagemagick,
|
|
||||||
ripgrep,
|
|
||||||
writeShellApplication,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
writeShellApplication {
|
|
||||||
name = "clipboard-manager";
|
|
||||||
runtimeInputs = [
|
|
||||||
cliphist
|
|
||||||
gawk
|
|
||||||
imagemagick
|
|
||||||
ripgrep
|
|
||||||
];
|
|
||||||
|
|
||||||
text = builtins.readFile ./script.sh;
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
set +o errexit
|
|
||||||
|
|
||||||
# Modified from https://github.com/sentriz/cliphist/blob/master/contrib/cliphist-wofi-img
|
|
||||||
|
|
||||||
# set up thumbnail directory
|
|
||||||
thumb_dir="/tmp/cliphist/thumbs"
|
|
||||||
mkdir -p "$thumb_dir"
|
|
||||||
|
|
||||||
cliphist_list="$(cliphist list)"
|
|
||||||
|
|
||||||
# delete thumbnails in cache but not in cliphist
|
|
||||||
for thumb in "$thumb_dir"/*; do
|
|
||||||
clip_id="${thumb##*/}"
|
|
||||||
clip_id="${clip_id%.*}"
|
|
||||||
check=$(rg <<< "$cliphist_list" "^$clip_id\s")
|
|
||||||
if [ -z "$check" ]; then
|
|
||||||
>&2 rm -v "$thumb"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# create thumbnail if image not processed already
|
|
||||||
read -r -d '' prog <<EOF
|
|
||||||
/^[0-9]+\s<meta http-equiv=/ { next }
|
|
||||||
|
|
||||||
match(\$0, /^([0-9]+)\s(\[\[\s)?binary.*(jpg|jpeg|png|bmp)/, grp) {
|
|
||||||
image = grp[1]"."grp[3]
|
|
||||||
system("[ -f $thumb_dir/"image" ] || echo " grp[1] "\\\\\t | cliphist decode | convert - -resize '256x256>' $thumb_dir/"image )
|
|
||||||
print "img:$thumb_dir/"image
|
|
||||||
next
|
|
||||||
}
|
|
||||||
|
|
||||||
1
|
|
||||||
EOF
|
|
||||||
|
|
||||||
output=$(gawk <<< "$cliphist_list" "$prog")
|
|
||||||
|
|
||||||
# Use a while loop with read to iterate over each line
|
|
||||||
echo "$output" | while IFS= read -r line; do
|
|
||||||
if [[ ! $line =~ ^img:/tmp/cliphist/thumbs ]]; then
|
|
||||||
[[ $line =~ ([0-9]+) ]]
|
|
||||||
line=${BASH_REMATCH[1]}
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$line"
|
|
||||||
done
|
|
|
@ -1 +0,0 @@
|
||||||
use flake "$FLAKE#node"
|
|
|
@ -1,40 +0,0 @@
|
||||||
import Brightness from './services/brightness.ts';
|
|
||||||
import GSR from './services/gpu-screen-recorder.ts';
|
|
||||||
import Pointers from './services/pointers.ts';
|
|
||||||
|
|
||||||
import AppLauncher from './ts/applauncher/main.ts';
|
|
||||||
import Bar from './ts/bar/binto.ts';
|
|
||||||
import Clipboard from './ts/clipboard/main.ts';
|
|
||||||
import Calendar from './ts/date/binto.ts';
|
|
||||||
import { NotifPopups, NotifCenter } from './ts/notifications/binto.ts';
|
|
||||||
import OSD from './ts/osd/main.ts';
|
|
||||||
import Powermenu from './ts/powermenu.ts';
|
|
||||||
import Screenshot from './ts/screenshot/main.ts';
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: add workspace indicator
|
|
||||||
App.config({
|
|
||||||
icons: './icons',
|
|
||||||
|
|
||||||
onConfigParsed: () => {
|
|
||||||
Brightness.capsName = 'input30::capslock';
|
|
||||||
globalThis.Brightness = Brightness;
|
|
||||||
globalThis.Pointers = Pointers;
|
|
||||||
setTimeout(() => {
|
|
||||||
globalThis.GSR = new GSR();
|
|
||||||
}, 1000);
|
|
||||||
},
|
|
||||||
|
|
||||||
windows: () => [
|
|
||||||
AppLauncher(),
|
|
||||||
Calendar(),
|
|
||||||
Clipboard(),
|
|
||||||
NotifCenter(),
|
|
||||||
Powermenu(),
|
|
||||||
Screenshot(),
|
|
||||||
|
|
||||||
Bar(),
|
|
||||||
NotifPopups(),
|
|
||||||
OSD(),
|
|
||||||
],
|
|
||||||
});
|
|
|
@ -1,452 +0,0 @@
|
||||||
import eslint from '@eslint/js';
|
|
||||||
import jsdoc from 'eslint-plugin-jsdoc';
|
|
||||||
import stylistic from '@stylistic/eslint-plugin';
|
|
||||||
import tseslint from 'typescript-eslint';
|
|
||||||
|
|
||||||
|
|
||||||
export default tseslint.config({
|
|
||||||
// @ts-expect-error this should work
|
|
||||||
files: ['**/*.js', '**/*.ts'],
|
|
||||||
ignores: ['node_modules/**', 'types/**'],
|
|
||||||
|
|
||||||
extends: [
|
|
||||||
eslint.configs.recommended,
|
|
||||||
jsdoc.configs['flat/recommended-typescript'],
|
|
||||||
stylistic.configs['recommended-flat'],
|
|
||||||
...tseslint.configs.recommended,
|
|
||||||
...tseslint.configs.stylistic,
|
|
||||||
],
|
|
||||||
|
|
||||||
rules: {
|
|
||||||
// JSDoc settings
|
|
||||||
'jsdoc/tag-lines': ['warn', 'any', { startLines: 1 }],
|
|
||||||
'jsdoc/check-line-alignment': ['warn', 'always', {
|
|
||||||
tags: ['param', 'arg', 'argument', 'property', 'prop'],
|
|
||||||
}],
|
|
||||||
'jsdoc/no-types': 'off',
|
|
||||||
|
|
||||||
// Newer settings
|
|
||||||
'@typescript-eslint/no-extraneous-class': ['off'],
|
|
||||||
'@typescript-eslint/no-implied-eval': ['off'],
|
|
||||||
'class-methods-use-this': 'off',
|
|
||||||
'@stylistic/no-multiple-empty-lines': 'off',
|
|
||||||
|
|
||||||
// Pre-flat config
|
|
||||||
'@typescript-eslint/no-unused-vars': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
args: 'all',
|
|
||||||
argsIgnorePattern: '^_',
|
|
||||||
caughtErrors: 'all',
|
|
||||||
caughtErrorsIgnorePattern: '^_',
|
|
||||||
destructuredArrayIgnorePattern: '^_',
|
|
||||||
varsIgnorePattern: '^_',
|
|
||||||
ignoreRestSiblings: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
'array-callback-return': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
allowImplicit: true,
|
|
||||||
checkForEach: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'no-constructor-return': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-unreachable-loop': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
ignore: [
|
|
||||||
'ForInStatement',
|
|
||||||
'ForOfStatement',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'no-use-before-define': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
functions: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'block-scoped-var': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'curly': [
|
|
||||||
'warn',
|
|
||||||
],
|
|
||||||
'default-case-last': [
|
|
||||||
'warn',
|
|
||||||
],
|
|
||||||
'default-param-last': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'eqeqeq': [
|
|
||||||
'error',
|
|
||||||
'smart',
|
|
||||||
],
|
|
||||||
'func-names': [
|
|
||||||
'warn',
|
|
||||||
'never',
|
|
||||||
],
|
|
||||||
'func-style': [
|
|
||||||
'warn',
|
|
||||||
'expression',
|
|
||||||
],
|
|
||||||
'logical-assignment-operators': [
|
|
||||||
'warn',
|
|
||||||
'always',
|
|
||||||
],
|
|
||||||
'no-array-constructor': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-empty-function': [
|
|
||||||
'warn',
|
|
||||||
],
|
|
||||||
'no-empty-static-block': [
|
|
||||||
'warn',
|
|
||||||
],
|
|
||||||
'no-extend-native': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-extra-bind': [
|
|
||||||
'warn',
|
|
||||||
],
|
|
||||||
'no-implicit-coercion': [
|
|
||||||
'warn',
|
|
||||||
],
|
|
||||||
'no-iterator': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-labels': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-lone-blocks': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-lonely-if': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-loop-func': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-magic-numbers': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
ignore: [
|
|
||||||
-1,
|
|
||||||
0.1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
2,
|
|
||||||
3,
|
|
||||||
4,
|
|
||||||
5,
|
|
||||||
10,
|
|
||||||
12,
|
|
||||||
33,
|
|
||||||
66,
|
|
||||||
100,
|
|
||||||
255,
|
|
||||||
360,
|
|
||||||
450,
|
|
||||||
500,
|
|
||||||
1000,
|
|
||||||
],
|
|
||||||
ignoreDefaultValues: true,
|
|
||||||
ignoreClassFieldInitialValues: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'no-multi-assign': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-new-wrappers': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-object-constructor': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-proto': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-return-assign': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-sequences': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-shadow': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
builtinGlobals: true,
|
|
||||||
allow: [
|
|
||||||
'Window',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'no-undef-init': [
|
|
||||||
'warn',
|
|
||||||
],
|
|
||||||
'no-undefined': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-useless-constructor': [
|
|
||||||
'warn',
|
|
||||||
],
|
|
||||||
'no-useless-escape': [
|
|
||||||
'off',
|
|
||||||
],
|
|
||||||
'no-useless-return': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-var': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'no-void': [
|
|
||||||
'off',
|
|
||||||
],
|
|
||||||
'no-with': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'object-shorthand': [
|
|
||||||
'error',
|
|
||||||
'always',
|
|
||||||
],
|
|
||||||
'one-var': [
|
|
||||||
'error',
|
|
||||||
'never',
|
|
||||||
],
|
|
||||||
'operator-assignment': [
|
|
||||||
'warn',
|
|
||||||
'always',
|
|
||||||
],
|
|
||||||
'prefer-arrow-callback': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'prefer-const': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'prefer-object-has-own': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'prefer-regex-literals': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'prefer-template': [
|
|
||||||
'warn',
|
|
||||||
],
|
|
||||||
'no-prototype-builtins': 'off',
|
|
||||||
'@typescript-eslint/no-var-requires': [
|
|
||||||
'off',
|
|
||||||
],
|
|
||||||
'@stylistic/array-bracket-newline': [
|
|
||||||
'warn',
|
|
||||||
'consistent',
|
|
||||||
],
|
|
||||||
'@stylistic/array-bracket-spacing': [
|
|
||||||
'warn',
|
|
||||||
'never',
|
|
||||||
],
|
|
||||||
'@stylistic/arrow-parens': [
|
|
||||||
'warn',
|
|
||||||
'always',
|
|
||||||
],
|
|
||||||
'@stylistic/brace-style': [
|
|
||||||
'warn',
|
|
||||||
'stroustrup',
|
|
||||||
],
|
|
||||||
'@stylistic/comma-dangle': [
|
|
||||||
'warn',
|
|
||||||
'always-multiline',
|
|
||||||
],
|
|
||||||
'@stylistic/comma-spacing': [
|
|
||||||
'warn',
|
|
||||||
{
|
|
||||||
before: false,
|
|
||||||
after: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@stylistic/comma-style': [
|
|
||||||
'error',
|
|
||||||
'last',
|
|
||||||
],
|
|
||||||
'@stylistic/dot-location': [
|
|
||||||
'error',
|
|
||||||
'property',
|
|
||||||
],
|
|
||||||
'@stylistic/function-call-argument-newline': [
|
|
||||||
'warn',
|
|
||||||
'consistent',
|
|
||||||
],
|
|
||||||
'@stylistic/function-paren-newline': [
|
|
||||||
'warn',
|
|
||||||
'consistent',
|
|
||||||
],
|
|
||||||
'@stylistic/indent': [
|
|
||||||
'warn',
|
|
||||||
4,
|
|
||||||
{
|
|
||||||
SwitchCase: 1,
|
|
||||||
ignoreComments: true,
|
|
||||||
ignoredNodes: ['TemplateLiteral > *'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@stylistic/key-spacing': [
|
|
||||||
'warn',
|
|
||||||
{
|
|
||||||
beforeColon: false,
|
|
||||||
afterColon: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@stylistic/keyword-spacing': [
|
|
||||||
'warn',
|
|
||||||
{
|
|
||||||
before: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@stylistic/linebreak-style': [
|
|
||||||
'error',
|
|
||||||
'unix',
|
|
||||||
],
|
|
||||||
'@stylistic/lines-between-class-members': [
|
|
||||||
'warn',
|
|
||||||
'always',
|
|
||||||
{
|
|
||||||
exceptAfterSingleLine: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@stylistic/max-len': [
|
|
||||||
'warn',
|
|
||||||
{
|
|
||||||
code: 105,
|
|
||||||
ignoreComments: true,
|
|
||||||
ignoreTrailingComments: true,
|
|
||||||
ignoreUrls: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@stylistic/multiline-ternary': [
|
|
||||||
'warn',
|
|
||||||
'always-multiline',
|
|
||||||
],
|
|
||||||
'@stylistic/new-parens': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'@stylistic/no-mixed-operators': [
|
|
||||||
'warn',
|
|
||||||
],
|
|
||||||
'@stylistic/no-mixed-spaces-and-tabs': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'@stylistic/no-multi-spaces': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'@stylistic/no-tabs': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'@stylistic/no-trailing-spaces': [
|
|
||||||
'error',
|
|
||||||
],
|
|
||||||
'@stylistic/no-whitespace-before-property': [
|
|
||||||
'warn',
|
|
||||||
],
|
|
||||||
'@stylistic/nonblock-statement-body-position': [
|
|
||||||
'error',
|
|
||||||
'below',
|
|
||||||
],
|
|
||||||
'@stylistic/object-curly-newline': [
|
|
||||||
'warn',
|
|
||||||
{
|
|
||||||
consistent: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@stylistic/object-curly-spacing': [
|
|
||||||
'warn',
|
|
||||||
'always',
|
|
||||||
],
|
|
||||||
'@stylistic/operator-linebreak': [
|
|
||||||
'warn',
|
|
||||||
'after',
|
|
||||||
],
|
|
||||||
'@stylistic/padded-blocks': [
|
|
||||||
'error',
|
|
||||||
'never',
|
|
||||||
],
|
|
||||||
'@stylistic/padding-line-between-statements': [
|
|
||||||
'warn',
|
|
||||||
{
|
|
||||||
blankLine: 'always',
|
|
||||||
prev: '*',
|
|
||||||
next: 'return',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
blankLine: 'always',
|
|
||||||
prev: [
|
|
||||||
'const',
|
|
||||||
'let',
|
|
||||||
'var',
|
|
||||||
],
|
|
||||||
next: '*',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
blankLine: 'any',
|
|
||||||
prev: [
|
|
||||||
'const',
|
|
||||||
'let',
|
|
||||||
'var',
|
|
||||||
],
|
|
||||||
next: [
|
|
||||||
'const',
|
|
||||||
'let',
|
|
||||||
'var',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
blankLine: 'always',
|
|
||||||
prev: [
|
|
||||||
'case',
|
|
||||||
'default',
|
|
||||||
],
|
|
||||||
next: '*',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@stylistic/quote-props': [
|
|
||||||
'error',
|
|
||||||
'consistent-as-needed',
|
|
||||||
],
|
|
||||||
'@stylistic/quotes': [
|
|
||||||
'error',
|
|
||||||
'single',
|
|
||||||
{
|
|
||||||
avoidEscape: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'@stylistic/semi': [
|
|
||||||
'error',
|
|
||||||
'always',
|
|
||||||
],
|
|
||||||
'@stylistic/semi-spacing': [
|
|
||||||
'warn',
|
|
||||||
],
|
|
||||||
'@stylistic/space-before-blocks': [
|
|
||||||
'warn',
|
|
||||||
],
|
|
||||||
'@stylistic/space-before-function-paren': [
|
|
||||||
'warn',
|
|
||||||
'never',
|
|
||||||
],
|
|
||||||
'@stylistic/space-infix-ops': [
|
|
||||||
'warn',
|
|
||||||
],
|
|
||||||
'@stylistic/spaced-comment': [
|
|
||||||
'warn',
|
|
||||||
'always',
|
|
||||||
],
|
|
||||||
'@stylistic/switch-colon-spacing': [
|
|
||||||
'warn',
|
|
||||||
],
|
|
||||||
'@stylistic/wrap-regex': [
|
|
||||||
'warn',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
|
177
nixosModules/ags/config/global-types.d.ts
vendored
177
nixosModules/ags/config/global-types.d.ts
vendored
|
@ -1,177 +0,0 @@
|
||||||
import { Widget } from 'types/@girs/gtk-3.0/gtk-3.0.cjs';
|
|
||||||
import GObject from 'types/@girs/gobject-2.0/gobject-2.0';
|
|
||||||
|
|
||||||
import { Variable as Var } from 'types/variable';
|
|
||||||
import { Widget as agsWidget } from 'types/widgets/widget';
|
|
||||||
export type AgsWidget = agsWidget<unknown> & Widget;
|
|
||||||
|
|
||||||
// Generic widgets
|
|
||||||
import AgsBox from 'types/widgets/box.ts';
|
|
||||||
export type BoxGeneric = AgsBox<unknown & Widget, unknown>;
|
|
||||||
|
|
||||||
import AgsCenterBox, { CenterBoxProps } from 'types/widgets/centerbox';
|
|
||||||
export type CenterBoxGeneric = AgsCenterBox<
|
|
||||||
unknown & Widget, unknown & Widget, unknown & Widget, unknown
|
|
||||||
>;
|
|
||||||
export type CenterBoxPropsGeneric = CenterBoxProps<
|
|
||||||
unknown & Widget, unknown & Widget, unknown & Widget, unknown
|
|
||||||
>;
|
|
||||||
|
|
||||||
import AgsEventBox from 'types/widgets/eventbox';
|
|
||||||
export type EventBoxGeneric = AgsEventBox<unknown & Widget, unknown>;
|
|
||||||
|
|
||||||
import AgsIcon, { IconProps } from 'types/widgets/icon';
|
|
||||||
export type IconGeneric = AgsIcon<unknown>;
|
|
||||||
export type IconPropsGeneric = IconProps<unknown>;
|
|
||||||
|
|
||||||
import AgsLabel from 'types/widgets/label';
|
|
||||||
export type LabelGeneric = AgsLabel<unknown>;
|
|
||||||
|
|
||||||
import AgsOverlay, { OverlayProps } from 'types/widgets/overlay';
|
|
||||||
export type OverlayGeneric = AgsOverlay<unknown & Widget, unknown>;
|
|
||||||
|
|
||||||
import AgsProgressBar from 'types/widgets/progressbar';
|
|
||||||
export type ProgressBarGeneric = AgsProgressBar<unknown & Widget, unknown>;
|
|
||||||
|
|
||||||
import AgsRevealer, { RevealerProps } from 'types/widgets/revealer';
|
|
||||||
export type RevealerGeneric = AgsRevealer<unknown & Widget, unknown>;
|
|
||||||
|
|
||||||
import AgsStack, { StackProps } from 'types/widgets/stack';
|
|
||||||
export type StackGeneric = AgsStack<Record<string, Widget>, unknown>;
|
|
||||||
|
|
||||||
import AgsScrollable from 'types/widgets/scrollable';
|
|
||||||
export type ScrollableGeneric = AgsScrollable<unkown & Widget, unknown>;
|
|
||||||
|
|
||||||
import AgsWindow from 'types/widgets/window';
|
|
||||||
export type WindowGeneric = AgsWindow<unknown & Widget, unknown>;
|
|
||||||
|
|
||||||
|
|
||||||
// For ./ts/applauncher/main.ts
|
|
||||||
import { Application } from 'types/service/applications.ts';
|
|
||||||
import { CursorBoxProps } from 'ts/misc/cursorbox';
|
|
||||||
export type AgsAppItem = AgsEventBox<Widget, { app: Application }
|
|
||||||
& CursorBoxProps<Widget, unknown>>;
|
|
||||||
|
|
||||||
// For ./ts/bar/hovers/keyboard.ts
|
|
||||||
export interface Keyboard {
|
|
||||||
address: string
|
|
||||||
name: string
|
|
||||||
rules: string
|
|
||||||
model: string
|
|
||||||
layout: string
|
|
||||||
variant: string
|
|
||||||
options: string
|
|
||||||
active_keymap: string
|
|
||||||
main: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
// For ./ts/bar/items/workspaces.ts
|
|
||||||
// TODO: improve type
|
|
||||||
export type Workspace = AgsRevealer<unknown & Widget, unknown & { id: number }>;
|
|
||||||
|
|
||||||
// For ./ts/bar/fullscreen.ts
|
|
||||||
export type DefaultProps = RevealerProps<CenterBoxGeneric>;
|
|
||||||
|
|
||||||
// For ./ts/media-player/gesture.ts
|
|
||||||
export interface Gesture {
|
|
||||||
attribute?: object
|
|
||||||
setup?(self: OverlayGeneric): void
|
|
||||||
props?: OverlayProps<unknown & Widget, unknown>
|
|
||||||
}
|
|
||||||
|
|
||||||
// For ./ts/media-player/mpris.ts
|
|
||||||
type PlayerDragProps = unknown & { dragging: boolean };
|
|
||||||
export type PlayerDrag = AgsCenterBox<
|
|
||||||
unknown & Widget, unknown & Widget, unknown & Widget, unknown & PlayerDragProps
|
|
||||||
>;
|
|
||||||
interface Colors {
|
|
||||||
imageAccent: string
|
|
||||||
buttonAccent: string
|
|
||||||
buttonText: string
|
|
||||||
hoverAccent: string
|
|
||||||
}
|
|
||||||
|
|
||||||
// For ./ts/media-player
|
|
||||||
export interface PlayerBoxProps {
|
|
||||||
bgStyle: string
|
|
||||||
player: MprisPlayer
|
|
||||||
}
|
|
||||||
export type PlayerBox = AgsCenterBox<
|
|
||||||
unknown & Widget, unknown & Widget, unknown & Widget, PlayerBoxProps
|
|
||||||
>;
|
|
||||||
export type PlayerOverlay = AgsOverlay<AgsWidget, {
|
|
||||||
players: Map
|
|
||||||
setup: boolean
|
|
||||||
dragging: boolean
|
|
||||||
includesWidget(playerW: PlayerBox): PlayerBox
|
|
||||||
showTopOnly(): void
|
|
||||||
moveToTop(player: PlayerBox): void
|
|
||||||
}>;
|
|
||||||
export interface PlayerButtonType {
|
|
||||||
player: MprisPlayer
|
|
||||||
colors: Var<Colors>
|
|
||||||
children: StackProps['children']
|
|
||||||
onClick: string
|
|
||||||
prop: string
|
|
||||||
}
|
|
||||||
|
|
||||||
// For ./ts/notifications/gesture.js
|
|
||||||
interface NotifGestureProps {
|
|
||||||
dragging: boolean
|
|
||||||
hovered: boolean
|
|
||||||
ready: boolean
|
|
||||||
id: number
|
|
||||||
slideAway(side: 'Left' | 'Right'): void
|
|
||||||
}
|
|
||||||
export type NotifGesture = AgsEventBox<BoxGeneric, NotifGestureProps>;
|
|
||||||
|
|
||||||
// For ./ts/osd/ctor.ts
|
|
||||||
export type OSDStack = AgsStack<unknown & Widget, {
|
|
||||||
popup(osd: string): void
|
|
||||||
}>;
|
|
||||||
export type ConnectFunc = (self?: ProgressBarGeneric) => void;
|
|
||||||
export interface OSD {
|
|
||||||
name: string
|
|
||||||
icon: IconPropsGeneric['icon']
|
|
||||||
info: {
|
|
||||||
mod: GObject.Object
|
|
||||||
signal?: string | string[]
|
|
||||||
logic?(self: ProgressBarGeneric): void
|
|
||||||
widget?: AgsWidget
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For ./ts/on-screen-keyboard
|
|
||||||
export type OskWindow = Window<BoxGeneric, {
|
|
||||||
startY: null | number
|
|
||||||
setVisible: (state: boolean) => void
|
|
||||||
killGestureSigs: () => void
|
|
||||||
setSlideUp: () => void
|
|
||||||
setSlideDown: () => void
|
|
||||||
}>;
|
|
||||||
|
|
||||||
// For CursorBox
|
|
||||||
import { CursorBox, CursorBoxProps } from 'ts/misc/cursorbox';
|
|
||||||
export type CursorBox = CursorBox;
|
|
||||||
export type CursorBoxProps = CursorBoxProps;
|
|
||||||
|
|
||||||
// For PopupWindow
|
|
||||||
export type HyprTransition = 'slide' | 'slide top' | 'slide bottom' | 'slide left' |
|
|
||||||
'slide right' | 'popin' | 'fade';
|
|
||||||
export type CloseType = 'none' | 'stay' | 'released' | 'clicked';
|
|
||||||
import { PopupWindow } from 'ts/misc/popup';
|
|
||||||
export type PopupWindow = PopupWindow;
|
|
||||||
|
|
||||||
// For ./ts/quick-settings
|
|
||||||
import { BluetoothDevice as BTDev } from 'types/service/bluetooth.ts';
|
|
||||||
export interface APType {
|
|
||||||
bssid: string
|
|
||||||
address: string
|
|
||||||
lastSeen: number
|
|
||||||
ssid: string
|
|
||||||
active: boolean
|
|
||||||
strength: number
|
|
||||||
iconName: string
|
|
||||||
}
|
|
||||||
export type APBox = AgsBox<unknown & Widget, { ap: Var<APType> }>;
|
|
||||||
export type DeviceBox = AgsBox<unknown & Widget, { dev: BTDev }>;
|
|
|
@ -1,52 +0,0 @@
|
||||||
const { execAsync, monitorFile } = Utils;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} host the name of the machine/user who's running ags
|
|
||||||
*/
|
|
||||||
const watchAndCompileSass = (host) => {
|
|
||||||
const reloadCss = () => {
|
|
||||||
const scss = `${App.configDir}/scss/${host}.scss`;
|
|
||||||
const css = `/tmp/ags-${host}/style.css`;
|
|
||||||
|
|
||||||
execAsync(`sass ${scss} ${css}`).then(() => {
|
|
||||||
App.resetCss();
|
|
||||||
App.applyCss(css);
|
|
||||||
}).catch(print);
|
|
||||||
};
|
|
||||||
|
|
||||||
monitorFile(
|
|
||||||
`${App.configDir}/scss`,
|
|
||||||
reloadCss,
|
|
||||||
);
|
|
||||||
reloadCss();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} host the name of the machine/user who's running ags
|
|
||||||
* @returns the config
|
|
||||||
*/
|
|
||||||
export const transpileTypeScript = async(host) => {
|
|
||||||
const outPath = `/tmp/ags-${host}/index.js`;
|
|
||||||
|
|
||||||
await execAsync([
|
|
||||||
'bash', '-c',
|
|
||||||
// Create the dir if it doesn't exist
|
|
||||||
`mkdir -p /tmp/ags-${host}; ` +
|
|
||||||
|
|
||||||
// Let bun see tsconfig.json
|
|
||||||
`cd ${App.configDir};` +
|
|
||||||
|
|
||||||
`bun build ${App.configDir}/${host === 'lockscreen' ? 'ts/lockscreen/main' : host}.ts ` +
|
|
||||||
'--external resource:///* ' +
|
|
||||||
'--external gi://* ' +
|
|
||||||
'--external cairo ' +
|
|
||||||
|
|
||||||
// Since bun wants to write in cwd, we just redirect stdin instead
|
|
||||||
`> ${outPath}`,
|
|
||||||
]).catch(print);
|
|
||||||
|
|
||||||
watchAndCompileSass(host);
|
|
||||||
|
|
||||||
return await import(`file://${outPath}`);
|
|
||||||
};
|
|
|
@ -1,3 +0,0 @@
|
||||||
import { transpileTypeScript } from './js/utils.js';
|
|
||||||
|
|
||||||
export default (await transpileTypeScript('lockscreen')).default;
|
|
BIN
nixosModules/ags/config/package-lock.json
generated
BIN
nixosModules/ags/config/package-lock.json
generated
Binary file not shown.
|
@ -1,18 +0,0 @@
|
||||||
{
|
|
||||||
"name": "ags-node-modules",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"main": "config.js",
|
|
||||||
"type": "module",
|
|
||||||
"dependencies": {
|
|
||||||
"@eslint/js": "9.13.0",
|
|
||||||
"@stylistic/eslint-plugin": "2.9.0",
|
|
||||||
"@types/eslint__js": "8.42.3",
|
|
||||||
"@types/node": "22.7.7",
|
|
||||||
"eslint": "9.13.0",
|
|
||||||
"eslint-plugin-jsdoc": "50.4.3",
|
|
||||||
"fzf": "0.5.2",
|
|
||||||
"jiti": "2.3.3",
|
|
||||||
"typescript": "5.6.3",
|
|
||||||
"typescript-eslint": "8.10.0"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
.applauncher {
|
|
||||||
all: unset;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
background-color: $bg;
|
|
||||||
color: #f8f8f2;
|
|
||||||
padding: 2px;
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
list,
|
|
||||||
row {
|
|
||||||
all: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
margin: 16.2px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
|
|
||||||
image,
|
|
||||||
entry {
|
|
||||||
all: unset;
|
|
||||||
border-radius: 9px;
|
|
||||||
color: #f8f8f2;
|
|
||||||
background-color: rgba(#44475a, 0.6);
|
|
||||||
border: 1px solid #44475a;
|
|
||||||
padding: 4.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
margin-right: 9px;
|
|
||||||
-gtk-icon-transform: scale(0.8);
|
|
||||||
font-size: 25.6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scrolledwindow {
|
|
||||||
padding: 10px;
|
|
||||||
padding-bottom: 0;
|
|
||||||
min-width: 900px;
|
|
||||||
min-height: 650px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.placeholder {
|
|
||||||
margin-top: 9px;
|
|
||||||
color: #f8f8f2;
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
all: unset;
|
|
||||||
transition: 200ms;
|
|
||||||
border-radius: 9px;
|
|
||||||
|
|
||||||
label {
|
|
||||||
transition: 200ms;
|
|
||||||
|
|
||||||
&.title {
|
|
||||||
margin-top: 20px;
|
|
||||||
color: #f8f8f2;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.description {
|
|
||||||
color: rgba(238, 238, 238, 0.7);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
transition: 200ms;
|
|
||||||
margin: 0 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: rgba($contrast-bg, 0.5);
|
|
||||||
box-shadow: inset 0 0 0 3px rgba(238, 238, 238, 0.03);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*:selected,
|
|
||||||
.app:hover,
|
|
||||||
.app:focus {
|
|
||||||
* {
|
|
||||||
font-weight: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
label.title {
|
|
||||||
color: $contrast-bg;
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
-gtk-icon-shadow: 2px 2px $contrast-bg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
.bar {
|
|
||||||
|
|
||||||
.clock,
|
|
||||||
.notif-panel {
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
padding: 4.5px 7px;
|
|
||||||
background-color: $bgfull;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sys-tray {
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
|
|
||||||
menubar {
|
|
||||||
background-color: $bgfull;
|
|
||||||
padding: 2.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
menuitem {
|
|
||||||
image {
|
|
||||||
color: #CBA6F7;
|
|
||||||
}
|
|
||||||
|
|
||||||
padding: 0 2px;
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-size: 25px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
menuitem:first-child image {
|
|
||||||
padding-left: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.current-window {
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
font-size: 18px;
|
|
||||||
padding-right: 7px;
|
|
||||||
background-color: $bgfull;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
.clipboard {
|
|
||||||
all: unset;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
background-color: $bg;
|
|
||||||
color: #f8f8f2;
|
|
||||||
padding: 2px;
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
list,
|
|
||||||
row {
|
|
||||||
all: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
margin: 16.2px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
|
|
||||||
image,
|
|
||||||
entry {
|
|
||||||
all: unset;
|
|
||||||
border-radius: 9px;
|
|
||||||
color: #f8f8f2;
|
|
||||||
background-color: rgba(#44475a, 0.6);
|
|
||||||
border: 1px solid #44475a;
|
|
||||||
padding: 4.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
margin-right: 9px;
|
|
||||||
-gtk-icon-transform: scale(0.8);
|
|
||||||
font-size: 25.6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scrolledwindow {
|
|
||||||
padding: 10px;
|
|
||||||
padding-bottom: 0;
|
|
||||||
min-width: 900px;
|
|
||||||
min-height: 750px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item {
|
|
||||||
all: unset;
|
|
||||||
transition: 200ms;
|
|
||||||
border-radius: 9px;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
*:selected .item,
|
|
||||||
*:hover .item,
|
|
||||||
*:focus .item {
|
|
||||||
background-color: #363449;
|
|
||||||
}
|
|
||||||
|
|
||||||
.down-arrow {
|
|
||||||
transition: all 500ms;
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
.date {
|
|
||||||
background-color: $bg;
|
|
||||||
color: $fg;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
}
|
|
||||||
|
|
||||||
.timebox {
|
|
||||||
margin: 30px 0;
|
|
||||||
|
|
||||||
.time-container {
|
|
||||||
.content {
|
|
||||||
font-weight: bolder;
|
|
||||||
font-size: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.divider {
|
|
||||||
margin: 8px 15px;
|
|
||||||
padding: 0 1px;
|
|
||||||
background: linear-gradient($red, $magenta, $blue, $cyan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.date-container {
|
|
||||||
margin-top: 2px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cal-box {
|
|
||||||
border-radius: 30px;
|
|
||||||
padding: 0 1rem .2rem;
|
|
||||||
color: $fg;
|
|
||||||
background-color: $bgfull;
|
|
||||||
border-bottom: 2px solid $contrast-bg;
|
|
||||||
border-top: 2px solid $contrast-bg;
|
|
||||||
margin: 0 12px 18px;
|
|
||||||
|
|
||||||
.cal {
|
|
||||||
font-size: 20px;
|
|
||||||
background-color: inherit;
|
|
||||||
padding: .5rem .10rem 0;
|
|
||||||
margin-left: 10px;
|
|
||||||
border-radius: 30px;
|
|
||||||
|
|
||||||
&>* {
|
|
||||||
border: solid 0 transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.highlight {
|
|
||||||
padding: 10rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
calendar:selected {
|
|
||||||
color: $cyan;
|
|
||||||
}
|
|
||||||
|
|
||||||
calendar.header {
|
|
||||||
color: $cyan;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
calendar.button {
|
|
||||||
color: $cyan;
|
|
||||||
}
|
|
||||||
|
|
||||||
calendar.highlight {
|
|
||||||
color: $green;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
calendar:indeterminate {
|
|
||||||
color: $lightblack;
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
.notification-center {
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
min-height: 700px;
|
|
||||||
min-width: 524px;
|
|
||||||
background: $bg;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
padding: 10px;
|
|
||||||
margin-top: 22px;
|
|
||||||
margin-bottom: 9px;
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-size: 22px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clear {
|
|
||||||
box {
|
|
||||||
all: unset;
|
|
||||||
transition: 200ms;
|
|
||||||
color: #eee;
|
|
||||||
background-color: #664C90;
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
padding: 4.5px 9px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover box {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-color: rgba(238, 238, 238, 0.154);
|
|
||||||
color: #f1f1f1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.disabled box {
|
|
||||||
box-shadow: none;
|
|
||||||
background-color: rgba(#664C90, 0.3);
|
|
||||||
color: rgba(238, 238, 238, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.notification-list-box {
|
|
||||||
background: $bgfull;
|
|
||||||
padding: 0 12px;
|
|
||||||
border-top: 2px solid $contrast-bg;
|
|
||||||
|
|
||||||
scrollbar {
|
|
||||||
all: unset;
|
|
||||||
border-radius: 8px;
|
|
||||||
border-top-left-radius: 0;
|
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
|
|
||||||
* {
|
|
||||||
all: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border-radius: 8px;
|
|
||||||
border-top-left-radius: 0;
|
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollbar.vertical {
|
|
||||||
transition: 200ms;
|
|
||||||
background-color: rgba(23, 23, 23, 0.3);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(23, 23, 23, 0.7);
|
|
||||||
|
|
||||||
slider {
|
|
||||||
background-color: rgba(238, 238, 238, 0.7);
|
|
||||||
min-width: .6em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
slider {
|
|
||||||
background-color: rgba(238, 238, 238, 0.5);
|
|
||||||
border-radius: 9px;
|
|
||||||
min-width: .4em;
|
|
||||||
min-height: 2em;
|
|
||||||
transition: 200ms;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.placeholder {
|
|
||||||
color: white;
|
|
||||||
|
|
||||||
image {
|
|
||||||
font-size: 7em;
|
|
||||||
text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6);
|
|
||||||
-gtk-icon-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6);
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-size: 1.2em;
|
|
||||||
text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6);
|
|
||||||
-gtk-icon-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,207 +0,0 @@
|
||||||
$background-color-1: rgba(238, 238, 238, 0.154);
|
|
||||||
$background-color-2: rgba(230, 112, 144, 0.5);
|
|
||||||
$background-color-3: rgba(238, 238, 238, 0.06);
|
|
||||||
$background-color-4: #51a4e7;
|
|
||||||
$background-color-5: transparent;
|
|
||||||
$background-color-6: #171717;
|
|
||||||
$background-color-7: rgba(23, 23, 23, 0.3);
|
|
||||||
$background-color-8: rgba(23, 23, 23, 0.7);
|
|
||||||
$background-color-9: rgba(238, 238, 238, 0.7);
|
|
||||||
$background-color-10: rgba(238, 238, 238, 0.5);
|
|
||||||
|
|
||||||
.notification.critical {
|
|
||||||
>box {
|
|
||||||
box-shadow: inset 0 0 0.5em 0 #e67090;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.notification {
|
|
||||||
>box {
|
|
||||||
all: unset;
|
|
||||||
box-shadow: 0 0 4.5px 0 rgba(0, 0, 0, 0.4);
|
|
||||||
margin: 9px 9px 0;
|
|
||||||
background-color: $bg;
|
|
||||||
padding: 16.2px;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.close-button {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-color: $background-color-1;
|
|
||||||
background-color: $background-color-2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
margin-right: 9px;
|
|
||||||
font-size: 1.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
font-size: .9em;
|
|
||||||
min-width: 350px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
margin-right: 9px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon.img {
|
|
||||||
border: 1px solid rgba(238, 238, 238, 0.03);
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
button {
|
|
||||||
all: unset;
|
|
||||||
transition: all 500ms;
|
|
||||||
background-color: $background-color-3;
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
font-size: 1.2em;
|
|
||||||
padding: 4.5px 9px;
|
|
||||||
margin: 9px 4.5px 0;
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
box-shadow: inset 0 0 0 1px #51a4e7;
|
|
||||||
background-color: $background-color-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-color: $background-color-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-image: linear-gradient(to right, #51a4e7, #6cb2eb);
|
|
||||||
background-color: $background-color-4;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:checked {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-image: linear-gradient(to right, #51a4e7, #6cb2eb);
|
|
||||||
background-color: $background-color-4;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:disabled {
|
|
||||||
box-shadow: none;
|
|
||||||
background-color: $background-color-5;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button.on {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-image: linear-gradient(to right, #51a4e7, #6cb2eb);
|
|
||||||
background-color: $background-color-4;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button.active {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-image: linear-gradient(to right, #51a4e7, #6cb2eb);
|
|
||||||
background-color: $background-color-4;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button.close-button {
|
|
||||||
all: unset;
|
|
||||||
transition: all 500ms;
|
|
||||||
background-color: $background-color-5;
|
|
||||||
background-image: none;
|
|
||||||
box-shadow: none;
|
|
||||||
margin-left: 9px;
|
|
||||||
min-width: 1.2em;
|
|
||||||
min-height: 1.2em;
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
box-shadow: inset 0 0 0 1px #51a4e7;
|
|
||||||
background-color: $background-color-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-color: $background-color-1;
|
|
||||||
background-color: $background-color-2;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-color: $background-color-4;
|
|
||||||
background-image: linear-gradient(#e67090, #e67090);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:checked {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-image: linear-gradient(to right, #51a4e7, #6cb2eb);
|
|
||||||
background-color: $background-color-4;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:disabled {
|
|
||||||
box-shadow: none;
|
|
||||||
background-color: $background-color-5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button.close-button.on {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-image: linear-gradient(to right, #51a4e7, #6cb2eb);
|
|
||||||
background-color: $background-color-4;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button.close-button.active {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-image: linear-gradient(to right, #51a4e7, #6cb2eb);
|
|
||||||
background-color: $background-color-4;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
.osd {
|
|
||||||
padding: 12px 20px;
|
|
||||||
background: rgba(40, 42, 54, 0.8);
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
|
|
||||||
label {
|
|
||||||
min-width: 170px;
|
|
||||||
}
|
|
||||||
|
|
||||||
progressbar:disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
progressbar {
|
|
||||||
min-height: 6px;
|
|
||||||
min-width: 170px;
|
|
||||||
border-radius: 999px;
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
|
|
||||||
trough {
|
|
||||||
background: #363847;
|
|
||||||
min-height: inherit;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
progress {
|
|
||||||
background: #79659f;
|
|
||||||
min-height: inherit;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
font-size: 2rem;
|
|
||||||
color: white;
|
|
||||||
margin-left: -0.4rem;
|
|
||||||
margin-right: 0.8rem;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
.powermenu {
|
|
||||||
background-color: $bg;
|
|
||||||
color: $fg;
|
|
||||||
padding: 10px;
|
|
||||||
font-family: "MesloLGS NF";
|
|
||||||
|
|
||||||
font-size: 70px;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
|
|
||||||
label {
|
|
||||||
min-width: 140px;
|
|
||||||
min-height: 130px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
margin: 5px 10px;
|
|
||||||
min-width: 80px;
|
|
||||||
transition: all ease .2s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: $bg-secondary;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: $bg-secondary;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
padding: 0 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.shutdown {
|
|
||||||
color: $red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reboot {
|
|
||||||
color: $magenta;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logout {
|
|
||||||
color: $yellow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.powermenu-clickhandler {
|
|
||||||
background-color: black;
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
.screenshot {
|
|
||||||
background-color: $bg;
|
|
||||||
color: $fg;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-size: 20pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
border-bottom: 2px solid $contrast-bg;
|
|
||||||
|
|
||||||
.header-btn {
|
|
||||||
transition: 200ms;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(23, 23, 23, 0.7);
|
|
||||||
|
|
||||||
image {
|
|
||||||
-gtk-icon-shadow: 1px 1px $contrast-bg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
margin: 10px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
font-size: 30px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scrolledwindow {
|
|
||||||
min-height: 400px;
|
|
||||||
min-width: 800px;
|
|
||||||
padding: 0 10px;
|
|
||||||
|
|
||||||
box {
|
|
||||||
.item-btn {
|
|
||||||
transition: 200ms;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(23, 23, 23, 0.7);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
font-size: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:first-child label {
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child label {
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
window,
|
|
||||||
button,
|
|
||||||
eventbox,
|
|
||||||
box,
|
|
||||||
progressbar,
|
|
||||||
trough,
|
|
||||||
undershoot {
|
|
||||||
all: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
@import './common';
|
|
||||||
@import './binto-widgets/applauncher';
|
|
||||||
@import './binto-widgets/bar';
|
|
||||||
@import './binto-widgets/clipboard';
|
|
||||||
@import './binto-widgets/date';
|
|
||||||
@import './binto-widgets/notification';
|
|
||||||
@import './binto-widgets/notification-center';
|
|
||||||
@import './binto-widgets/osd';
|
|
||||||
@import './binto-widgets/powermenu';
|
|
||||||
@import './binto-widgets/screenshot';
|
|
|
@ -1,65 +0,0 @@
|
||||||
$darkbg: #0b0d16;
|
|
||||||
$bg: rgba(40, 42, 54, 0.8); // rgba(69, 71, 90, 0.3); #0d0f18;
|
|
||||||
$bgfull: rgb(40, 42, 54);
|
|
||||||
$contrast-bg: rgba(189, 147, 249, 0.8);
|
|
||||||
$contrast-bg-full: rgba(189, 147, 249, 1);
|
|
||||||
$bg-secondary: rgba(#382c4a, 0.8);
|
|
||||||
$bg-secondary-alt: #a5b6cf;
|
|
||||||
$fg: #a5b6cf;
|
|
||||||
$fg-dim: #a5b6cf;
|
|
||||||
$watermelon: #dd6777;
|
|
||||||
|
|
||||||
// Aliases
|
|
||||||
$background: $bg;
|
|
||||||
$background-secondary: $bg-secondary;
|
|
||||||
$background-secondary-alt: $bg-secondary-alt;
|
|
||||||
$foreground: $fg;
|
|
||||||
$foreground-dim: $fg-dim;
|
|
||||||
|
|
||||||
$black: #151720;
|
|
||||||
$dimblack: #1a1c25;
|
|
||||||
$lightblack: #262831;
|
|
||||||
$red: #dd6777;
|
|
||||||
$blue: #86aaec;
|
|
||||||
$cyan: #93cee9;
|
|
||||||
$blue-desaturated: #93cee9;
|
|
||||||
$magenta: #c296eb;
|
|
||||||
$purple: #c296eb;
|
|
||||||
$green: #90ceaa;
|
|
||||||
$aquamarine: #90ceaa;
|
|
||||||
$yellow: #ecd3a0;
|
|
||||||
$accent: $blue;
|
|
||||||
$javacafe-magenta: #c296eb;
|
|
||||||
$javacafe-blue: #86aaec;
|
|
||||||
|
|
||||||
|
|
||||||
scrolledwindow {
|
|
||||||
|
|
||||||
scrollbar,
|
|
||||||
scrollbar * {
|
|
||||||
all: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollbar.vertical {
|
|
||||||
transition: 200ms;
|
|
||||||
background-color: rgba(23, 23, 23, 0.3);
|
|
||||||
margin: 20px 0;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(23, 23, 23, 0.7);
|
|
||||||
|
|
||||||
slider {
|
|
||||||
background-color: rgba(238, 238, 238, 0.7);
|
|
||||||
min-width: .6em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
slider {
|
|
||||||
background-color: rgba(238, 238, 238, 0.5);
|
|
||||||
border-radius: 9px;
|
|
||||||
min-width: .4em;
|
|
||||||
min-height: 2em;
|
|
||||||
transition: 200ms;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
@import './common';
|
|
||||||
|
|
||||||
window {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clock {
|
|
||||||
font-size: 80pt;
|
|
||||||
font-family: 'Ubuntu Mono';
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
.applauncher {
|
|
||||||
all: unset;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
border-radius: 25px;
|
|
||||||
background-color: $bg;
|
|
||||||
color: #f8f8f2;
|
|
||||||
padding: 2px;
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
list,
|
|
||||||
row {
|
|
||||||
all: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
margin: 16.2px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
|
|
||||||
image,
|
|
||||||
entry {
|
|
||||||
all: unset;
|
|
||||||
border-radius: 9px;
|
|
||||||
color: #f8f8f2;
|
|
||||||
background-color: rgba(#44475a, 0.6);
|
|
||||||
border: 1px solid #44475a;
|
|
||||||
padding: 4.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
margin-right: 9px;
|
|
||||||
-gtk-icon-transform: scale(0.8);
|
|
||||||
font-size: 25.6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scrolledwindow {
|
|
||||||
padding: 10px;
|
|
||||||
padding-bottom: 0;
|
|
||||||
min-width: 700px;
|
|
||||||
min-height: 450px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.placeholder {
|
|
||||||
margin-top: 9px;
|
|
||||||
color: #f8f8f2;
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app {
|
|
||||||
all: unset;
|
|
||||||
transition: 200ms;
|
|
||||||
border-radius: 9px;
|
|
||||||
|
|
||||||
label {
|
|
||||||
transition: 200ms;
|
|
||||||
|
|
||||||
&.title {
|
|
||||||
color: #f8f8f2;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.description {
|
|
||||||
color: rgba(238, 238, 238, 0.7);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
transition: 200ms;
|
|
||||||
margin: 0 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: rgba($contrast-bg, 0.5);
|
|
||||||
box-shadow: inset 0 0 0 3px rgba(238, 238, 238, 0.03);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*:selected,
|
|
||||||
.app:hover,
|
|
||||||
.app:focus {
|
|
||||||
* {
|
|
||||||
font-weight: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
label.title {
|
|
||||||
color: $contrast-bg;
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
-gtk-icon-shadow: 2px 2px $contrast-bg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
.clipboard {
|
|
||||||
all: unset;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
border-radius: 25px;
|
|
||||||
background-color: $bg;
|
|
||||||
color: #f8f8f2;
|
|
||||||
padding: 2px;
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
list,
|
|
||||||
row {
|
|
||||||
all: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
margin: 16.2px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
|
|
||||||
image,
|
|
||||||
entry {
|
|
||||||
all: unset;
|
|
||||||
border-radius: 9px;
|
|
||||||
color: #f8f8f2;
|
|
||||||
background-color: rgba(#44475a, 0.6);
|
|
||||||
border: 1px solid #44475a;
|
|
||||||
padding: 4.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
margin-right: 9px;
|
|
||||||
-gtk-icon-transform: scale(0.8);
|
|
||||||
font-size: 25.6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scrolledwindow {
|
|
||||||
padding: 10px;
|
|
||||||
padding-bottom: 0;
|
|
||||||
min-width: 900px;
|
|
||||||
min-height: 750px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item {
|
|
||||||
all: unset;
|
|
||||||
transition: 200ms;
|
|
||||||
border-radius: 9px;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
*:selected .item,
|
|
||||||
*:hover .item,
|
|
||||||
*:focus .item {
|
|
||||||
background-color: #363449;
|
|
||||||
}
|
|
||||||
|
|
||||||
.down-arrow {
|
|
||||||
transition: all 500ms;
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
.date {
|
|
||||||
background-color: $bg;
|
|
||||||
color: $fg;
|
|
||||||
border-radius: 30px;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
}
|
|
||||||
|
|
||||||
.timebox {
|
|
||||||
margin: 30px 0;
|
|
||||||
|
|
||||||
.time-container {
|
|
||||||
.content {
|
|
||||||
font-weight: bolder;
|
|
||||||
font-size: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.divider {
|
|
||||||
margin: 8px 15px;
|
|
||||||
padding: 0 1px;
|
|
||||||
background: linear-gradient($red, $magenta, $blue, $cyan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.date-container {
|
|
||||||
margin-top: 2px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cal-box {
|
|
||||||
border-radius: 30px;
|
|
||||||
padding: 0 1rem .2rem;
|
|
||||||
color: $fg;
|
|
||||||
background-color: $bgfull;
|
|
||||||
border-bottom: 2px solid $contrast-bg;
|
|
||||||
border-top: 2px solid $contrast-bg;
|
|
||||||
margin: 0 12px 18px;
|
|
||||||
|
|
||||||
.cal {
|
|
||||||
font-size: 20px;
|
|
||||||
background-color: inherit;
|
|
||||||
padding: .5rem .10rem 0;
|
|
||||||
margin-left: 10px;
|
|
||||||
border-radius: 30px;
|
|
||||||
|
|
||||||
&>* {
|
|
||||||
border: solid 0 transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.highlight {
|
|
||||||
padding: 10rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
calendar:selected {
|
|
||||||
color: $cyan;
|
|
||||||
}
|
|
||||||
|
|
||||||
calendar.header {
|
|
||||||
color: $cyan;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
calendar.button {
|
|
||||||
color: $cyan;
|
|
||||||
}
|
|
||||||
|
|
||||||
calendar.highlight {
|
|
||||||
color: $green;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
calendar:indeterminate {
|
|
||||||
color: $lightblack;
|
|
||||||
}
|
|
|
@ -1,113 +0,0 @@
|
||||||
.notification-center {
|
|
||||||
min-height: 700px;
|
|
||||||
min-width: 524px;
|
|
||||||
background: $bg;
|
|
||||||
border-radius: 30px;
|
|
||||||
border-top-right-radius: 0;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
padding: 10px;
|
|
||||||
margin-top: 22px;
|
|
||||||
margin-bottom: 9px;
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-size: 22px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clear {
|
|
||||||
box {
|
|
||||||
all: unset;
|
|
||||||
transition: 200ms;
|
|
||||||
border-radius: 9px;
|
|
||||||
color: #eee;
|
|
||||||
background-color: #664C90;
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
padding: 4.5px 9px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover box {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-color: rgba(238, 238, 238, 0.154);
|
|
||||||
color: #f1f1f1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.disabled box {
|
|
||||||
box-shadow: none;
|
|
||||||
background-color: rgba(#664C90, 0.3);
|
|
||||||
color: rgba(238, 238, 238, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.notification-list-box {
|
|
||||||
background: $bgfull;
|
|
||||||
padding: 0 12px;
|
|
||||||
border-radius: 30px;
|
|
||||||
border-top: 2px solid $contrast-bg;
|
|
||||||
|
|
||||||
scrollbar {
|
|
||||||
all: unset;
|
|
||||||
border-radius: 8px;
|
|
||||||
border-top-left-radius: 0;
|
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
|
|
||||||
* {
|
|
||||||
all: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border-radius: 8px;
|
|
||||||
border-top-left-radius: 0;
|
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollbar.vertical {
|
|
||||||
transition: 200ms;
|
|
||||||
background-color: rgba(23, 23, 23, 0.3);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(23, 23, 23, 0.7);
|
|
||||||
|
|
||||||
slider {
|
|
||||||
background-color: rgba(238, 238, 238, 0.7);
|
|
||||||
min-width: .6em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
slider {
|
|
||||||
background-color: rgba(238, 238, 238, 0.5);
|
|
||||||
border-radius: 9px;
|
|
||||||
min-width: .4em;
|
|
||||||
min-height: 2em;
|
|
||||||
transition: 200ms;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.placeholder {
|
|
||||||
color: white;
|
|
||||||
|
|
||||||
image {
|
|
||||||
font-size: 7em;
|
|
||||||
text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6);
|
|
||||||
-gtk-icon-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6);
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-size: 1.2em;
|
|
||||||
text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6);
|
|
||||||
-gtk-icon-shadow: 2px 2px 2px rgba(0, 0, 0, 0.6);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,210 +0,0 @@
|
||||||
$background-color-1: rgba(238, 238, 238, 0.154);
|
|
||||||
$background-color-2: rgba(230, 112, 144, 0.5);
|
|
||||||
$background-color-3: rgba(238, 238, 238, 0.06);
|
|
||||||
$background-color-4: #51a4e7;
|
|
||||||
$background-color-5: transparent;
|
|
||||||
$background-color-6: #171717;
|
|
||||||
$background-color-7: rgba(23, 23, 23, 0.3);
|
|
||||||
$background-color-8: rgba(23, 23, 23, 0.7);
|
|
||||||
$background-color-9: rgba(238, 238, 238, 0.7);
|
|
||||||
$background-color-10: rgba(238, 238, 238, 0.5);
|
|
||||||
|
|
||||||
.notification.critical {
|
|
||||||
>box {
|
|
||||||
box-shadow: inset 0 0 0.5em 0 #e67090;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.notification {
|
|
||||||
>box {
|
|
||||||
all: unset;
|
|
||||||
margin: 9px 9px 0;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
border-radius: 15px;
|
|
||||||
background-color: $bg;
|
|
||||||
padding: 16.2px;
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.close-button {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-color: $background-color-1;
|
|
||||||
background-color: $background-color-2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
margin-right: 9px;
|
|
||||||
font-size: 1.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
font-size: .9em;
|
|
||||||
min-width: 350px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
border-radius: 7.2px;
|
|
||||||
margin-right: 9px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon.img {
|
|
||||||
border: 1px solid rgba(238, 238, 238, 0.03);
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
button {
|
|
||||||
all: unset;
|
|
||||||
transition: all 500ms;
|
|
||||||
background-color: $background-color-3;
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
border-radius: 7.2px;
|
|
||||||
font-size: 1.2em;
|
|
||||||
padding: 4.5px 9px;
|
|
||||||
margin: 9px 4.5px 0;
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
box-shadow: inset 0 0 0 1px #51a4e7;
|
|
||||||
background-color: $background-color-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-color: $background-color-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-image: linear-gradient(to right, #51a4e7, #6cb2eb);
|
|
||||||
background-color: $background-color-4;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:checked {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-image: linear-gradient(to right, #51a4e7, #6cb2eb);
|
|
||||||
background-color: $background-color-4;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:disabled {
|
|
||||||
box-shadow: none;
|
|
||||||
background-color: $background-color-5;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button.on {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-image: linear-gradient(to right, #51a4e7, #6cb2eb);
|
|
||||||
background-color: $background-color-4;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button.active {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-image: linear-gradient(to right, #51a4e7, #6cb2eb);
|
|
||||||
background-color: $background-color-4;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button.close-button {
|
|
||||||
all: unset;
|
|
||||||
transition: all 500ms;
|
|
||||||
background-color: $background-color-5;
|
|
||||||
background-image: none;
|
|
||||||
box-shadow: none;
|
|
||||||
margin-left: 9px;
|
|
||||||
border-radius: 7.2px;
|
|
||||||
min-width: 1.2em;
|
|
||||||
min-height: 1.2em;
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
box-shadow: inset 0 0 0 1px #51a4e7;
|
|
||||||
background-color: $background-color-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-color: $background-color-1;
|
|
||||||
background-color: $background-color-2;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-color: $background-color-4;
|
|
||||||
background-image: linear-gradient(#e67090, #e67090);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:checked {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-image: linear-gradient(to right, #51a4e7, #6cb2eb);
|
|
||||||
background-color: $background-color-4;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:disabled {
|
|
||||||
box-shadow: none;
|
|
||||||
background-color: $background-color-5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button.close-button.on {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-image: linear-gradient(to right, #51a4e7, #6cb2eb);
|
|
||||||
background-color: $background-color-4;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button.close-button.active {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03);
|
|
||||||
background-image: linear-gradient(to right, #51a4e7, #6cb2eb);
|
|
||||||
background-color: $background-color-4;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 0 0 1px rgba(238, 238, 238, 0.03), inset 0 0 0 99px rgba(238, 238, 238, 0.154);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
.osd {
|
|
||||||
padding: 12px 20px;
|
|
||||||
border-radius: 999px;
|
|
||||||
background: rgba(40, 42, 54, 0.8);
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
|
|
||||||
label {
|
|
||||||
min-width: 170px;
|
|
||||||
}
|
|
||||||
|
|
||||||
progressbar:disabled {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
progressbar {
|
|
||||||
min-height: 6px;
|
|
||||||
min-width: 170px;
|
|
||||||
border-radius: 999px;
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
|
|
||||||
trough {
|
|
||||||
background: #363847;
|
|
||||||
min-height: inherit;
|
|
||||||
border-radius: inherit;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
progress {
|
|
||||||
background: #79659f;
|
|
||||||
min-height: inherit;
|
|
||||||
border-radius: inherit;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
font-size: 2rem;
|
|
||||||
color: white;
|
|
||||||
margin-left: -0.4rem;
|
|
||||||
margin-right: 0.8rem;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
.powermenu {
|
|
||||||
background-color: $bg;
|
|
||||||
color: $fg;
|
|
||||||
padding: 10px;
|
|
||||||
font-family: "MesloLGS NF";
|
|
||||||
|
|
||||||
/* font-family: Iosevka Nerd Font; */
|
|
||||||
font-size: 70px;
|
|
||||||
border-radius: 30px;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
|
|
||||||
label {
|
|
||||||
min-width: 140px;
|
|
||||||
min-height: 130px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
margin: 5px 10px;
|
|
||||||
border-radius: 12px;
|
|
||||||
min-width: 80px;
|
|
||||||
transition: all ease .2s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: $bg-secondary;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: $bg-secondary;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 0 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.shutdown {
|
|
||||||
color: $red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reboot {
|
|
||||||
color: $magenta;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logout {
|
|
||||||
color: $yellow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.powermenu-clickhandler {
|
|
||||||
background-color: black;
|
|
||||||
}
|
|
|
@ -1,76 +0,0 @@
|
||||||
.screenshot {
|
|
||||||
background-color: $bg;
|
|
||||||
color: $fg;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
border-radius: 25px;
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-size: 20pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
border-bottom: 2px solid $contrast-bg;
|
|
||||||
|
|
||||||
.header-btn {
|
|
||||||
transition: 200ms;
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&.active {
|
|
||||||
background-color: rgba(23, 23, 23, 0.7);
|
|
||||||
|
|
||||||
image {
|
|
||||||
-gtk-icon-shadow: 1px 1px $contrast-bg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
margin: 10px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
font-size: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
border-top-left-radius: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
border-top-right-radius: 25px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scrolledwindow {
|
|
||||||
min-height: 400px;
|
|
||||||
min-width: 800px;
|
|
||||||
padding: 0 10px;
|
|
||||||
|
|
||||||
box {
|
|
||||||
.item-btn {
|
|
||||||
transition: 200ms;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(23, 23, 23, 0.7);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
image {
|
|
||||||
font-size: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:first-child label {
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child label {
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
.sys-tray {
|
|
||||||
padding: 5px;
|
|
||||||
background-color: $bg;
|
|
||||||
border-radius: 80px;
|
|
||||||
border: 2px solid $bg-secondary;
|
|
||||||
transition: background-color 0.5s ease-in-out,
|
|
||||||
border 0.5s ease-in-out;
|
|
||||||
|
|
||||||
menuitem {
|
|
||||||
image {
|
|
||||||
color: #CBA6F7;
|
|
||||||
}
|
|
||||||
|
|
||||||
background-color: transparent;
|
|
||||||
padding: 0 2px;
|
|
||||||
border-radius: 100%;
|
|
||||||
transition: all 0.5s ease-in-out;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border-radius: 100%;
|
|
||||||
transition: all 0.5s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
|
||||||
font-size: 25px;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
menubar {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,123 +0,0 @@
|
||||||
.bar {
|
|
||||||
margin: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.current-window {
|
|
||||||
color: #CBA6F7;
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.osk-toggle,
|
|
||||||
.tablet-toggle,
|
|
||||||
.heart-toggle {
|
|
||||||
font-size: 28px;
|
|
||||||
min-height: 40px;
|
|
||||||
min-width: 53px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.heart-toggle {
|
|
||||||
font-size: 28px;
|
|
||||||
min-height: 40px;
|
|
||||||
color: #CBA6F7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notif-panel {
|
|
||||||
font-size: 20px;
|
|
||||||
min-height: 37px;
|
|
||||||
min-width: 105px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.quick-settings-toggle {
|
|
||||||
font-size: 24px;
|
|
||||||
min-height: 40px;
|
|
||||||
min-width: 40px;
|
|
||||||
padding-right: 4px;
|
|
||||||
margin-left: -3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toggle-off {
|
|
||||||
background-color: $bg;
|
|
||||||
color: #CBA6F7;
|
|
||||||
border-radius: 80px;
|
|
||||||
border: 2px solid $bg-secondary;
|
|
||||||
transition: background-color 0.5s ease-in-out,
|
|
||||||
border 0.5s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toggle-on {
|
|
||||||
background-color: $bg;
|
|
||||||
color: #CBA6F7;
|
|
||||||
border-radius: 80px;
|
|
||||||
border: 2px solid $contrast-bg;
|
|
||||||
transition: background-color 0.5s ease-in-out,
|
|
||||||
border 0.5s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toggle-on:hover,
|
|
||||||
.toggle-off:hover {
|
|
||||||
background-color: rgba(127, 132, 156, 0.4);
|
|
||||||
transition: background-color 0.5s ease-in-out,
|
|
||||||
border 0.5s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clock {
|
|
||||||
font-size: 20px;
|
|
||||||
padding: 0 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.audio,
|
|
||||||
.bluetooth,
|
|
||||||
.brightness,
|
|
||||||
.keyboard {
|
|
||||||
padding: 0 10px;
|
|
||||||
font-size: 20px;
|
|
||||||
margin-right: -10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.network {
|
|
||||||
padding: 0 10px;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-text {
|
|
||||||
color: $bg;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.battery {
|
|
||||||
padding: 0 10px;
|
|
||||||
font-size: 20px;
|
|
||||||
|
|
||||||
.battery-indicator {
|
|
||||||
&.charging {
|
|
||||||
color: green;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.charged {
|
|
||||||
// TODO: charged battery style
|
|
||||||
}
|
|
||||||
|
|
||||||
&.low {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
icon {
|
|
||||||
.charging {
|
|
||||||
// TODO: charging battery style
|
|
||||||
}
|
|
||||||
|
|
||||||
.discharging {
|
|
||||||
// TODO: discharging battery style
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tooltip {
|
|
||||||
background: rgba(0, 0, 0, 0.6);
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
.bar {
|
|
||||||
.workspaces {
|
|
||||||
background-color: $bg;
|
|
||||||
border-radius: 80px;
|
|
||||||
border: 2px solid $bg-secondary;
|
|
||||||
padding: 3px 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.button {
|
|
||||||
margin: 0 2.5px;
|
|
||||||
min-height: 22px;
|
|
||||||
min-width: 22px;
|
|
||||||
border-radius: 100%;
|
|
||||||
border: 2px solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.occupied {
|
|
||||||
border: 2px solid $bg;
|
|
||||||
background: $contrast-bg;
|
|
||||||
transition: background-color 0.6s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.urgent {
|
|
||||||
border: 2px solid $bg;
|
|
||||||
background: red;
|
|
||||||
transition: background-color 0.6s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active {
|
|
||||||
border: 2px solid #50fa7b;
|
|
||||||
transition: margin-left 0.5s cubic-bezier(0.165, 0.84, 0.44, 1);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
window,
|
|
||||||
button,
|
|
||||||
eventbox,
|
|
||||||
box,
|
|
||||||
progressbar,
|
|
||||||
trough,
|
|
||||||
undershoot {
|
|
||||||
all: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
@import './common';
|
|
||||||
@import './wim-widgets/powermenu';
|
|
||||||
@import './wim-widgets/traybuttons';
|
|
||||||
@import './wim-widgets/workspaces';
|
|
||||||
@import './wim-widgets/systray';
|
|
||||||
@import './wim-widgets/notification-center';
|
|
||||||
@import './wim-widgets/notification';
|
|
||||||
@import './wim-widgets/date';
|
|
||||||
@import './wim-widgets/quick-settings';
|
|
||||||
@import './wim-widgets/player';
|
|
||||||
@import './wim-widgets/applauncher';
|
|
||||||
@import './wim-widgets/osd';
|
|
||||||
@import './wim-widgets/osk';
|
|
||||||
@import './wim-widgets/clipboard';
|
|
||||||
@import './wim-widgets/screenshot';
|
|
|
@ -1,151 +0,0 @@
|
||||||
const { exec, execAsync } = Utils;
|
|
||||||
|
|
||||||
const KBD = 'tpacpi::kbd_backlight';
|
|
||||||
const INTERVAL = 500;
|
|
||||||
const SCREEN_ICONS = {
|
|
||||||
90: 'display-brightness-high-symbolic',
|
|
||||||
70: 'display-brightness-medium-symbolic',
|
|
||||||
20: 'display-brightness-low-symbolic',
|
|
||||||
5: 'display-brightness-off-symbolic',
|
|
||||||
};
|
|
||||||
|
|
||||||
class Brightness extends Service {
|
|
||||||
static {
|
|
||||||
Service.register(this, {
|
|
||||||
screen: ['float'],
|
|
||||||
kbd: ['float'],
|
|
||||||
caps: ['int'],
|
|
||||||
}, {
|
|
||||||
'screen-icon': ['string', 'rw'],
|
|
||||||
'caps-icon': ['string', 'rw'],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#kbd = 0;
|
|
||||||
#kbdMax = 0;
|
|
||||||
#screen = 0;
|
|
||||||
#screenIcon = 'display-brightness-symbolic';
|
|
||||||
#capsName = 'input0::capslock';
|
|
||||||
#caps = 0;
|
|
||||||
#capsIcon = 'caps-lock-symbolic';
|
|
||||||
|
|
||||||
get capsName() {
|
|
||||||
return this.#capsName;
|
|
||||||
}
|
|
||||||
|
|
||||||
set capsName(value: string) {
|
|
||||||
this.#capsName = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get kbd() {
|
|
||||||
return this.#kbd;
|
|
||||||
}
|
|
||||||
|
|
||||||
set kbd(value) {
|
|
||||||
if (value < 0 || value > this.#kbdMax) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
execAsync(`brightnessctl -d ${KBD} s ${value} -q`)
|
|
||||||
.then(() => {
|
|
||||||
this.#kbd = value;
|
|
||||||
this.emit('kbd', this.#kbd);
|
|
||||||
})
|
|
||||||
.catch(console.error);
|
|
||||||
}
|
|
||||||
|
|
||||||
get screen() {
|
|
||||||
return this.#screen;
|
|
||||||
}
|
|
||||||
|
|
||||||
set screen(percent) {
|
|
||||||
if (percent < 0) {
|
|
||||||
percent = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (percent > 1) {
|
|
||||||
percent = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
execAsync(`brightnessctl s ${percent * 100}% -q`)
|
|
||||||
.then(() => {
|
|
||||||
this.#screen = percent;
|
|
||||||
this.#getScreenIcon();
|
|
||||||
this.emit('screen', this.#screen);
|
|
||||||
})
|
|
||||||
.catch(console.error);
|
|
||||||
}
|
|
||||||
|
|
||||||
get screenIcon() {
|
|
||||||
return this.#screenIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
get caps() {
|
|
||||||
return this.#caps;
|
|
||||||
}
|
|
||||||
|
|
||||||
get capsIcon() {
|
|
||||||
return this.#capsIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
try {
|
|
||||||
this.#monitorKbdState();
|
|
||||||
this.#kbdMax = Number(exec(`brightnessctl -d ${KBD} m`));
|
|
||||||
this.#caps = Number(exec(`bash -c brightnessctl -d ${this.#capsName} g`));
|
|
||||||
this.#screen = Number(exec('brightnessctl g')) / Number(exec('brightnessctl m'));
|
|
||||||
}
|
|
||||||
catch (_e) {
|
|
||||||
console.error('missing dependancy: brightnessctl');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#getScreenIcon() {
|
|
||||||
const brightness = this.#screen * 100;
|
|
||||||
|
|
||||||
// eslint-disable-next-line
|
|
||||||
for (const threshold of [4, 19, 69, 89]) {
|
|
||||||
if (brightness > threshold + 1) {
|
|
||||||
this.#screenIcon = SCREEN_ICONS[threshold + 1];
|
|
||||||
this.notify('screen-icon');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchCapsState() {
|
|
||||||
execAsync(`brightnessctl -d ${this.#capsName} g`)
|
|
||||||
.then((out) => {
|
|
||||||
this.#caps = Number(out);
|
|
||||||
this.#capsIcon = this.#caps ?
|
|
||||||
'caps-lock-symbolic' :
|
|
||||||
'capslock-disabled-symbolic';
|
|
||||||
|
|
||||||
this.notify('caps-icon');
|
|
||||||
this.emit('caps', this.#caps);
|
|
||||||
})
|
|
||||||
.catch(logError);
|
|
||||||
}
|
|
||||||
|
|
||||||
#monitorKbdState() {
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
execAsync(`brightnessctl -d ${KBD} g`).then(
|
|
||||||
(out) => {
|
|
||||||
if (parseInt(out) !== this.#kbd) {
|
|
||||||
this.#kbd = parseInt(out);
|
|
||||||
this.emit('kbd', this.#kbd);
|
|
||||||
|
|
||||||
return this.#kbd;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
).catch(() => {
|
|
||||||
// @ts-expect-error this works in ags
|
|
||||||
interval.destroy();
|
|
||||||
});
|
|
||||||
}, INTERVAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const brightnessService = new Brightness();
|
|
||||||
|
|
||||||
export default brightnessService;
|
|
|
@ -1,147 +0,0 @@
|
||||||
const { execAsync, subprocess } = Utils;
|
|
||||||
|
|
||||||
|
|
||||||
class Clipboard extends Service {
|
|
||||||
static {
|
|
||||||
Service.register(this, {
|
|
||||||
'clip-added': ['jsobject'],
|
|
||||||
'history-searched': [],
|
|
||||||
}, {
|
|
||||||
clips: ['jsobject'],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static _MAX_CLIPS = 100;
|
|
||||||
|
|
||||||
// Class Attributes
|
|
||||||
private _clips_left = 0;
|
|
||||||
|
|
||||||
private _clips = new Map<number, { clip: string, isImage: boolean }>();
|
|
||||||
|
|
||||||
get clips() {
|
|
||||||
return this._clips;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this._getHistory();
|
|
||||||
this._watchClipboard();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public Class Methods
|
|
||||||
public copyOldItem(key: string | number): void {
|
|
||||||
execAsync([
|
|
||||||
'bash', '-c', `cliphist list | grep '^${key}' | cliphist decode | wl-copy`,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private Class Methods
|
|
||||||
private _decrementClipsLeft() {
|
|
||||||
if (--this._clips_left === 0) {
|
|
||||||
this.emit('history-searched');
|
|
||||||
// this is necessary when not putting a cap on clip amount
|
|
||||||
// exec(`prlimit --pid ${exec('pgrep ags')} --nofile=1024:`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _decodeItem(index: string): Promise<string | null> {
|
|
||||||
try {
|
|
||||||
const decodedItem = await execAsync([
|
|
||||||
'bash', '-c', `cliphist list | grep -a ${index} | cliphist decode`,
|
|
||||||
]);
|
|
||||||
|
|
||||||
this._decrementClipsLeft();
|
|
||||||
|
|
||||||
return decodedItem;
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
this._decrementClipsLeft();
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _addClip(newClip: [number, { clip: string, isImage: boolean }]) {
|
|
||||||
if (
|
|
||||||
![...this.clips.values()]
|
|
||||||
.map((c) => c.clip)
|
|
||||||
.includes(newClip[1].clip)
|
|
||||||
) {
|
|
||||||
this._clips.set(...newClip);
|
|
||||||
this.emit('clip-added', newClip);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const oldClip = [...this.clips.entries()]
|
|
||||||
.find(([_, { clip }]) => clip === newClip[1].clip);
|
|
||||||
|
|
||||||
if (oldClip && oldClip[0] < newClip[0]) {
|
|
||||||
this.clips.delete(oldClip[0]);
|
|
||||||
this._clips.set(...newClip);
|
|
||||||
this.emit('clip-added', newClip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _getHistory(n = Clipboard._MAX_CLIPS) {
|
|
||||||
// this is necessary when not putting a cap on clip amount
|
|
||||||
// exec(`prlimit --pid ${exec('pgrep ags')} --nofile=10024:`);
|
|
||||||
|
|
||||||
// This command comes from '../../clipboard/script.sh'
|
|
||||||
execAsync('clipboard-manager').then((out) => {
|
|
||||||
const rawClips = out.split('\n');
|
|
||||||
|
|
||||||
this._clips_left = Math.min(rawClips.length - 1, n);
|
|
||||||
|
|
||||||
rawClips.forEach(async(clip, i) => {
|
|
||||||
if (i > n) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clip.includes('img')) {
|
|
||||||
this._decrementClipsLeft();
|
|
||||||
|
|
||||||
const newClip: [number, { clip: string, isImage: boolean }] = [
|
|
||||||
parseInt((clip.match('[0-9]+') ?? [''])[0]),
|
|
||||||
{
|
|
||||||
clip,
|
|
||||||
isImage: true,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
this._addClip(newClip);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const decodedClip = await this._decodeItem(clip);
|
|
||||||
|
|
||||||
if (decodedClip) {
|
|
||||||
const newClip: [number, { clip: string, isImage: boolean }] = [
|
|
||||||
parseInt(clip),
|
|
||||||
{
|
|
||||||
clip: decodedClip,
|
|
||||||
isImage: false,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
this._addClip(newClip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}).catch((error) => console.error(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
private _watchClipboard() {
|
|
||||||
subprocess(
|
|
||||||
['wl-paste', '--watch', 'echo'],
|
|
||||||
() => {
|
|
||||||
this._getHistory(1);
|
|
||||||
},
|
|
||||||
() => { /**/ },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const clipboard = new Clipboard();
|
|
||||||
|
|
||||||
export default clipboard;
|
|
|
@ -1,80 +0,0 @@
|
||||||
const { execAsync, subprocess } = Utils;
|
|
||||||
|
|
||||||
const Notifications = await Service.import('notifications');
|
|
||||||
|
|
||||||
const APP_NAME = 'gpu-screen-recorder';
|
|
||||||
const START_APP_ID = 2345;
|
|
||||||
const ICON_NAME = 'nvidia';
|
|
||||||
|
|
||||||
|
|
||||||
class GSR extends Service {
|
|
||||||
static {
|
|
||||||
Service.register(this, {}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
#appID = START_APP_ID;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
subprocess(
|
|
||||||
['gsr-start'],
|
|
||||||
(path) => {
|
|
||||||
Notifications.getNotification(this.#appID)?.close();
|
|
||||||
|
|
||||||
const notifId = Notifications.Notify(
|
|
||||||
APP_NAME,
|
|
||||||
++this.#appID,
|
|
||||||
ICON_NAME,
|
|
||||||
'Replay Saved',
|
|
||||||
`Saved to ${path}`,
|
|
||||||
['folder', 'Open Folder', 'video', 'Open Video', 'kdenlive', 'Edit in kdenlive'],
|
|
||||||
{},
|
|
||||||
Notifications.popupTimeout,
|
|
||||||
);
|
|
||||||
|
|
||||||
Notifications.getNotification(notifId)?.connect(
|
|
||||||
'invoked',
|
|
||||||
(_, actionId: string) => {
|
|
||||||
if (actionId === 'folder') {
|
|
||||||
execAsync([
|
|
||||||
'xdg-open',
|
|
||||||
path.substring(0, path.lastIndexOf('/')),
|
|
||||||
]).catch(print);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (actionId === 'video') {
|
|
||||||
execAsync(['xdg-open', path]).catch(print);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (actionId === 'kdenlive') {
|
|
||||||
execAsync([
|
|
||||||
'bash',
|
|
||||||
'-c',
|
|
||||||
`kdenlive -i ${path}`,
|
|
||||||
]).catch(print);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
() => { /**/ },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
saveReplay() {
|
|
||||||
execAsync(['gpu-save-replay']).then(() => {
|
|
||||||
Notifications.Notify(
|
|
||||||
APP_NAME,
|
|
||||||
this.#appID,
|
|
||||||
ICON_NAME,
|
|
||||||
'Saving Replay',
|
|
||||||
'Last 20 minutes',
|
|
||||||
[],
|
|
||||||
{},
|
|
||||||
Notifications.popupTimeout,
|
|
||||||
);
|
|
||||||
}).catch(console.error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default GSR;
|
|
|
@ -1,228 +0,0 @@
|
||||||
const Hyprland = await Service.import('hyprland');
|
|
||||||
const { subprocess } = Utils;
|
|
||||||
|
|
||||||
const ON_RELEASE_TRIGGERS = [
|
|
||||||
'released',
|
|
||||||
'TOUCH_UP',
|
|
||||||
'HOLD_END',
|
|
||||||
];
|
|
||||||
const ON_CLICK_TRIGGERS = [
|
|
||||||
'pressed',
|
|
||||||
'TOUCH_DOWN',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Types
|
|
||||||
import { PopupWindow } from 'global-types';
|
|
||||||
import { Subprocess } from 'types/@girs/gio-2.0/gio-2.0.cjs';
|
|
||||||
interface Layer {
|
|
||||||
address: string
|
|
||||||
x: number
|
|
||||||
y: number
|
|
||||||
w: number
|
|
||||||
h: number
|
|
||||||
namespace: string
|
|
||||||
}
|
|
||||||
interface Levels {
|
|
||||||
0?: Layer[] | null
|
|
||||||
1?: Layer[] | null
|
|
||||||
2?: Layer[] | null
|
|
||||||
3?: Layer[] | null
|
|
||||||
}
|
|
||||||
interface Layers {
|
|
||||||
levels: Levels
|
|
||||||
}
|
|
||||||
interface CursorPos {
|
|
||||||
x: number
|
|
||||||
y: number
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Pointers extends Service {
|
|
||||||
static {
|
|
||||||
Service.register(this, {
|
|
||||||
'proc-started': ['boolean'],
|
|
||||||
'proc-destroyed': ['boolean'],
|
|
||||||
'device-fetched': ['boolean'],
|
|
||||||
'new-line': ['string'],
|
|
||||||
'released': ['string'],
|
|
||||||
'clicked': ['string'],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#process = null as Subprocess | null;
|
|
||||||
#lastLine = '';
|
|
||||||
#pointers = [] as string[];
|
|
||||||
|
|
||||||
get process() {
|
|
||||||
return this.#process;
|
|
||||||
}
|
|
||||||
|
|
||||||
get lastLine() {
|
|
||||||
return this.#lastLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
get pointers() {
|
|
||||||
return this.#pointers;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.#initAppConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
startProc() {
|
|
||||||
if (this.#process) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.#process = subprocess(
|
|
||||||
['libinput', 'debug-events'],
|
|
||||||
(output) => {
|
|
||||||
if (output.includes('cancelled')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ON_RELEASE_TRIGGERS.some((p) => output.includes(p))) {
|
|
||||||
this.#lastLine = output;
|
|
||||||
Pointers.detectClickedOutside('released');
|
|
||||||
this.emit('released', output);
|
|
||||||
this.emit('new-line', output);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ON_CLICK_TRIGGERS.some((p) => output.includes(p))) {
|
|
||||||
this.#lastLine = output;
|
|
||||||
Pointers.detectClickedOutside('clicked');
|
|
||||||
this.emit('clicked', output);
|
|
||||||
this.emit('new-line', output);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
this.emit('proc-started', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
killProc() {
|
|
||||||
if (this.#process) {
|
|
||||||
this.#process.force_exit();
|
|
||||||
this.#process = null;
|
|
||||||
this.emit('proc-destroyed', true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#initAppConnection() {
|
|
||||||
App.connect('window-toggled', () => {
|
|
||||||
const anyVisibleAndClosable =
|
|
||||||
(App.windows as PopupWindow[]).some((w) => {
|
|
||||||
const closable = w.close_on_unfocus &&
|
|
||||||
!(
|
|
||||||
w.close_on_unfocus === 'none' ||
|
|
||||||
w.close_on_unfocus === 'stay'
|
|
||||||
);
|
|
||||||
|
|
||||||
return w.visible && closable;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (anyVisibleAndClosable) {
|
|
||||||
this.startProc();
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
this.killProc();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static detectClickedOutside(clickStage: string) {
|
|
||||||
const toClose = ((App.windows as PopupWindow[])).some((w) => {
|
|
||||||
const closable = (
|
|
||||||
w.close_on_unfocus &&
|
|
||||||
w.close_on_unfocus === clickStage
|
|
||||||
);
|
|
||||||
|
|
||||||
return w.visible && closable;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!toClose) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Hyprland.messageAsync('j/layers').then((response) => {
|
|
||||||
const layers = JSON.parse(response) as { Layers: Layers };
|
|
||||||
|
|
||||||
Hyprland.messageAsync('j/cursorpos').then((res) => {
|
|
||||||
const pos = JSON.parse(res) as CursorPos;
|
|
||||||
|
|
||||||
Object.values(layers).forEach((key) => {
|
|
||||||
const overlayLayer = key.levels['3'];
|
|
||||||
|
|
||||||
if (overlayLayer) {
|
|
||||||
const noCloseWidgetsNames = [
|
|
||||||
'bar-',
|
|
||||||
'osk',
|
|
||||||
];
|
|
||||||
|
|
||||||
const getNoCloseWidgets = (names: string[]) => {
|
|
||||||
const arr = [] as Layer[];
|
|
||||||
|
|
||||||
names.forEach((name) => {
|
|
||||||
arr.push(
|
|
||||||
overlayLayer.find(
|
|
||||||
(n) => n.namespace.startsWith(name),
|
|
||||||
) ||
|
|
||||||
// Return an empty Layer if widget doesn't exist
|
|
||||||
{
|
|
||||||
address: '',
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
w: 0,
|
|
||||||
h: 0,
|
|
||||||
namespace: '',
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return arr;
|
|
||||||
};
|
|
||||||
const clickIsOnWidget = (w: Layer) => {
|
|
||||||
return pos.x > w.x && pos.x < w.x + w.w &&
|
|
||||||
pos.y > w.y && pos.y < w.y + w.h;
|
|
||||||
};
|
|
||||||
|
|
||||||
const noCloseWidgets =
|
|
||||||
getNoCloseWidgets(noCloseWidgetsNames);
|
|
||||||
|
|
||||||
const widgets = overlayLayer.filter((n) => {
|
|
||||||
let window = null as null | PopupWindow;
|
|
||||||
|
|
||||||
if (App.windows.some((win) =>
|
|
||||||
win.name === n.namespace)) {
|
|
||||||
window = (App
|
|
||||||
.getWindow(n.namespace) as PopupWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
return window &&
|
|
||||||
window.close_on_unfocus &&
|
|
||||||
window.close_on_unfocus ===
|
|
||||||
clickStage;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (noCloseWidgets.some(clickIsOnWidget)) {
|
|
||||||
// Don't handle clicks when on certain widgets
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
widgets.forEach(
|
|
||||||
(w) => {
|
|
||||||
if (!(pos.x > w.x && pos.x < w.x + w.w &&
|
|
||||||
pos.y > w.y && pos.y < w.y + w.h)) {
|
|
||||||
App.closeWindow(w.namespace);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}).catch(print);
|
|
||||||
}).catch(print);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default new Pointers();
|
|
|
@ -1,143 +0,0 @@
|
||||||
const { subprocess } = Utils;
|
|
||||||
|
|
||||||
const SCREEN = '/dev/input/by-path/platform-AMDI0010\:00-event';
|
|
||||||
|
|
||||||
const GESTURE_VERIF = [
|
|
||||||
'LR', // Left to Right
|
|
||||||
'RL', // Right to Left
|
|
||||||
'DU', // Down to Up
|
|
||||||
'UD', // Up to Down
|
|
||||||
'DLUR', // Down to Left to Up to Right (clockwise motion from Down)
|
|
||||||
'DRUL', // Down to Right to Up to Left (counter-clockwise from Down)
|
|
||||||
'URDL', // Up to Right to Down to Left (clockwise motion from Up)
|
|
||||||
'ULDR', // Up to Left to Down to Right (counter-clockwise from Up)
|
|
||||||
];
|
|
||||||
const EDGE_VERIF = [
|
|
||||||
'*', // Any
|
|
||||||
'N', // None
|
|
||||||
'L', // Left
|
|
||||||
'R', // Right
|
|
||||||
'T', // Top
|
|
||||||
'B', // Bottom
|
|
||||||
'TL', // Top left
|
|
||||||
'TR', // Top right
|
|
||||||
'BL', // Bottom left
|
|
||||||
'BR', // Bottom right
|
|
||||||
];
|
|
||||||
const DISTANCE_VERIF = [
|
|
||||||
'*', // Any
|
|
||||||
'S', // Short
|
|
||||||
'M', // Medium
|
|
||||||
'L', // Large
|
|
||||||
];
|
|
||||||
|
|
||||||
// Types
|
|
||||||
import { Subprocess } from 'types/@girs/gio-2.0/gio-2.0.cjs';
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: add actmode param
|
|
||||||
// TODO: support multiple daemons for different thresholds
|
|
||||||
class TouchGestures extends Service {
|
|
||||||
static {
|
|
||||||
Service.register(this, {
|
|
||||||
'daemon-started': ['boolean'],
|
|
||||||
'daemon-destroyed': ['boolean'],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#gestures = new Map();
|
|
||||||
#gestureDaemon = null as Subprocess | null;
|
|
||||||
|
|
||||||
get gestures() {
|
|
||||||
return this.#gestures;
|
|
||||||
}
|
|
||||||
|
|
||||||
get gestureDaemon() {
|
|
||||||
return this.#gestureDaemon;
|
|
||||||
}
|
|
||||||
|
|
||||||
addGesture({
|
|
||||||
name,
|
|
||||||
nFingers = '1',
|
|
||||||
gesture,
|
|
||||||
edge = '*',
|
|
||||||
distance = '*',
|
|
||||||
command,
|
|
||||||
}) {
|
|
||||||
gesture = String(gesture).toUpperCase();
|
|
||||||
if (!GESTURE_VERIF.includes(gesture)) {
|
|
||||||
logError('Wrong gesture id');
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
edge = String(edge).toUpperCase();
|
|
||||||
if (!EDGE_VERIF.includes(edge)) {
|
|
||||||
logError('Wrong edge id');
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
distance = String(distance).toUpperCase();
|
|
||||||
if (!DISTANCE_VERIF.includes(distance)) {
|
|
||||||
logError('Wrong distance id');
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof command !== 'string') {
|
|
||||||
globalThis[name] = command;
|
|
||||||
command = `ags -r "${name}()"`;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.#gestures.set(name, [
|
|
||||||
'-g',
|
|
||||||
`${nFingers},${gesture},${edge},${distance},${command}`,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (this.#gestureDaemon) {
|
|
||||||
this.killDaemon();
|
|
||||||
}
|
|
||||||
this.startDaemon();
|
|
||||||
}
|
|
||||||
|
|
||||||
startDaemon() {
|
|
||||||
if (this.#gestureDaemon) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let command = [
|
|
||||||
'lisgd', '-d', SCREEN,
|
|
||||||
// Orientation
|
|
||||||
'-o', '0',
|
|
||||||
// Threshold of gesture recognized
|
|
||||||
'-t', '125',
|
|
||||||
// Leniency of gesture angle
|
|
||||||
'-r', '25',
|
|
||||||
// Timeout time
|
|
||||||
'-m', '3200',
|
|
||||||
];
|
|
||||||
|
|
||||||
this.#gestures.forEach((gesture) => {
|
|
||||||
command = command.concat(gesture);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.#gestureDaemon = subprocess(
|
|
||||||
command,
|
|
||||||
() => { /**/ },
|
|
||||||
);
|
|
||||||
this.emit('daemon-started', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
killDaemon() {
|
|
||||||
if (this.#gestureDaemon) {
|
|
||||||
this.#gestureDaemon.force_exit();
|
|
||||||
this.#gestureDaemon = null;
|
|
||||||
this.emit('daemon-destroyed', true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const touchGesturesService = new TouchGestures();
|
|
||||||
|
|
||||||
export default touchGesturesService;
|
|
|
@ -1,63 +0,0 @@
|
||||||
const { Box, Icon, Label } = Widget;
|
|
||||||
const { lookUpIcon } = Utils;
|
|
||||||
|
|
||||||
import CursorBox from '../misc/cursorbox.ts';
|
|
||||||
|
|
||||||
/* Types */
|
|
||||||
import { Application } from 'types/service/applications.ts';
|
|
||||||
|
|
||||||
|
|
||||||
export default (app: Application) => {
|
|
||||||
const icon = Icon({ size: 42 });
|
|
||||||
const iconString = app.app.get_string('Icon');
|
|
||||||
|
|
||||||
if (app.icon_name) {
|
|
||||||
if (lookUpIcon(app.icon_name)) {
|
|
||||||
icon.icon = app.icon_name;
|
|
||||||
}
|
|
||||||
else if (iconString && iconString !== 'nix-snowflake') {
|
|
||||||
icon.icon = iconString;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
icon.icon = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const textBox = Box({
|
|
||||||
vertical: true,
|
|
||||||
vpack: 'start',
|
|
||||||
|
|
||||||
children: [
|
|
||||||
Label({
|
|
||||||
class_name: 'title',
|
|
||||||
label: app.name,
|
|
||||||
xalign: 0,
|
|
||||||
truncate: 'end',
|
|
||||||
}),
|
|
||||||
|
|
||||||
Label({
|
|
||||||
class_name: 'description',
|
|
||||||
label: app.description || '',
|
|
||||||
wrap: true,
|
|
||||||
xalign: 0,
|
|
||||||
justification: 'left',
|
|
||||||
}),
|
|
||||||
|
|
||||||
Label(),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
return CursorBox({
|
|
||||||
hexpand: true,
|
|
||||||
class_name: 'app',
|
|
||||||
|
|
||||||
attribute: { app },
|
|
||||||
|
|
||||||
child: Box({
|
|
||||||
children: [
|
|
||||||
icon,
|
|
||||||
textBox,
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,26 +0,0 @@
|
||||||
/* Types */
|
|
||||||
import { Application } from 'types/service/applications.ts';
|
|
||||||
|
|
||||||
|
|
||||||
const bash = async(strings: TemplateStringsArray | string, ...values: unknown[]) => {
|
|
||||||
const cmd = typeof strings === 'string' ?
|
|
||||||
strings :
|
|
||||||
strings.flatMap((str, i) => `${str}${values[i] ?? ''}`)
|
|
||||||
.join('');
|
|
||||||
|
|
||||||
return Utils.execAsync(['bash', '-c', cmd]).catch((err) => {
|
|
||||||
console.error(cmd, err);
|
|
||||||
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const launchApp = (app: Application) => {
|
|
||||||
const exe = app.executable
|
|
||||||
.split(/\s+/)
|
|
||||||
.filter((str) => !str.startsWith('%') && !str.startsWith('@'))
|
|
||||||
.join(' ');
|
|
||||||
|
|
||||||
bash(`${exe} &`);
|
|
||||||
app.frequency += 1;
|
|
||||||
};
|
|
|
@ -1,76 +0,0 @@
|
||||||
const Applications = await Service.import('applications');
|
|
||||||
|
|
||||||
import { Fzf, FzfResultItem } from 'fzf';
|
|
||||||
|
|
||||||
import SortedList from '../misc/sorted-list.ts';
|
|
||||||
import AppItem from './app-item.ts';
|
|
||||||
|
|
||||||
import { launchApp } from './launch.ts';
|
|
||||||
|
|
||||||
/* Types */
|
|
||||||
import { Application } from 'types/service/applications.ts';
|
|
||||||
import { AgsAppItem } from 'global-types';
|
|
||||||
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
let fzfResults = [] as FzfResultItem<Application>[];
|
|
||||||
|
|
||||||
return SortedList({
|
|
||||||
name: 'applauncher',
|
|
||||||
class_name: 'applauncher',
|
|
||||||
transition: 'slide top',
|
|
||||||
|
|
||||||
on_select: (r) => {
|
|
||||||
App.closeWindow('win-applauncher');
|
|
||||||
launchApp((r.get_child() as AgsAppItem).attribute.app);
|
|
||||||
},
|
|
||||||
|
|
||||||
setup_list: (list, entry) => {
|
|
||||||
Applications.query('')
|
|
||||||
.flatMap((app) => AppItem(app))
|
|
||||||
.forEach((ch) => {
|
|
||||||
list.add(ch);
|
|
||||||
});
|
|
||||||
|
|
||||||
list.show_all();
|
|
||||||
|
|
||||||
list.set_sort_func((a, b) => {
|
|
||||||
const row1 = (a.get_children()[0] as AgsAppItem).attribute.app;
|
|
||||||
const row2 = (b.get_children()[0] as AgsAppItem).attribute.app;
|
|
||||||
|
|
||||||
if (entry.text === '' || entry.text === '-') {
|
|
||||||
a.set_visible(true);
|
|
||||||
b.set_visible(true);
|
|
||||||
|
|
||||||
return row2.frequency - row1.frequency;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const s1 = fzfResults.find((r) => r.item.name === row1.name)?.score ?? 0;
|
|
||||||
const s2 = fzfResults.find((r) => r.item.name === row2.name)?.score ?? 0;
|
|
||||||
|
|
||||||
a.set_visible(s1 !== 0);
|
|
||||||
b.set_visible(s2 !== 0);
|
|
||||||
|
|
||||||
return s2 - s1;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
on_text_change: (text, list, placeholder) => {
|
|
||||||
const fzf = new Fzf(Applications.list, {
|
|
||||||
selector: (app) => app.name + app.executable,
|
|
||||||
|
|
||||||
tiebreakers: [
|
|
||||||
(a, b) => b.item.frequency - a.item.frequency,
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
fzfResults = fzf.find(text);
|
|
||||||
list.invalidate_sort();
|
|
||||||
|
|
||||||
const visibleApps = list.get_children().filter((row) => row.visible).length;
|
|
||||||
|
|
||||||
placeholder.reveal_child = visibleApps <= 0;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,57 +0,0 @@
|
||||||
const { Box, CenterBox } = Widget;
|
|
||||||
|
|
||||||
import Separator from '../misc/separator.ts';
|
|
||||||
import { get_gdkmonitor_from_desc } from '../lib.ts';
|
|
||||||
|
|
||||||
import BarRevealer from './fullscreen.ts';
|
|
||||||
|
|
||||||
import Clock from './items/cal-opener.ts';
|
|
||||||
import CurrentWindow from './items/current-window';
|
|
||||||
import NotifButton from './items/notif-button.ts';
|
|
||||||
import SysTray from './items/systray.ts';
|
|
||||||
|
|
||||||
const PADDING = 20;
|
|
||||||
|
|
||||||
export default () => BarRevealer({
|
|
||||||
gdkmonitor: get_gdkmonitor_from_desc('desc:Acer Technologies Acer K212HQL T3EAA0014201'),
|
|
||||||
exclusivity: 'exclusive',
|
|
||||||
anchor: ['bottom', 'left', 'right'],
|
|
||||||
bar: Box({
|
|
||||||
vertical: true,
|
|
||||||
children: [
|
|
||||||
CenterBox({
|
|
||||||
class_name: 'bar',
|
|
||||||
hexpand: true,
|
|
||||||
|
|
||||||
start_widget: Box({
|
|
||||||
hpack: 'start',
|
|
||||||
children: [
|
|
||||||
Separator(PADDING),
|
|
||||||
|
|
||||||
SysTray(),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
|
|
||||||
center_widget: Box({
|
|
||||||
children: [
|
|
||||||
CurrentWindow(),
|
|
||||||
|
|
||||||
Separator(PADDING / 2),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
|
|
||||||
end_widget: Box({
|
|
||||||
hpack: 'end',
|
|
||||||
children: [
|
|
||||||
NotifButton(),
|
|
||||||
Separator(PADDING / 2),
|
|
||||||
Clock(),
|
|
||||||
|
|
||||||
Separator(PADDING),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
Separator(PADDING, { vertical: true }),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
});
|
|
|
@ -1,156 +0,0 @@
|
||||||
const Hyprland = await Service.import('hyprland');
|
|
||||||
const { Box, EventBox, Revealer, Window } = Widget;
|
|
||||||
|
|
||||||
import Gdk from 'gi://Gdk?version=3.0';
|
|
||||||
|
|
||||||
import {
|
|
||||||
get_hyprland_monitor_desc,
|
|
||||||
get_monitor_desc_from_id,
|
|
||||||
} from '../lib.ts';
|
|
||||||
|
|
||||||
|
|
||||||
const FullscreenState = Variable({
|
|
||||||
monitors: [] as string[],
|
|
||||||
clientAddrs: new Map() as Map<string, string>,
|
|
||||||
});
|
|
||||||
|
|
||||||
Hyprland.connect('event', (hyprObj) => {
|
|
||||||
const arrayEquals = (a1: unknown[], a2: unknown[]) =>
|
|
||||||
a1.sort().toString() === a2.sort().toString();
|
|
||||||
|
|
||||||
const mapEquals = (m1: Map<string, string>, m2: Map<string, string>) =>
|
|
||||||
m1.size === m2.size &&
|
|
||||||
Array.from(m1.keys()).every((key) => m1.get(key) === m2.get(key));
|
|
||||||
|
|
||||||
const fs = FullscreenState.value;
|
|
||||||
const fsClients = hyprObj.clients.filter((c) => {
|
|
||||||
const mon = Hyprland.getMonitor(c.monitor);
|
|
||||||
|
|
||||||
return c.fullscreen &&
|
|
||||||
c.workspace.id === mon?.activeWorkspace.id;
|
|
||||||
});
|
|
||||||
|
|
||||||
const monitors = fsClients.map((c) =>
|
|
||||||
get_monitor_desc_from_id(c.monitor));
|
|
||||||
|
|
||||||
const clientAddrs = new Map(fsClients.map((c) => [
|
|
||||||
get_monitor_desc_from_id(c.monitor),
|
|
||||||
c.address,
|
|
||||||
]));
|
|
||||||
|
|
||||||
const hasChanged =
|
|
||||||
!arrayEquals(monitors, fs.monitors) ||
|
|
||||||
!mapEquals(clientAddrs, fs.clientAddrs);
|
|
||||||
|
|
||||||
if (hasChanged) {
|
|
||||||
FullscreenState.setValue({
|
|
||||||
monitors,
|
|
||||||
clientAddrs,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default ({
|
|
||||||
anchor,
|
|
||||||
bar,
|
|
||||||
gdkmonitor = Gdk.Display.get_default()?.get_monitor(0) as Gdk.Monitor,
|
|
||||||
...rest
|
|
||||||
}) => {
|
|
||||||
const monitor = get_hyprland_monitor_desc(gdkmonitor);
|
|
||||||
const BarVisible = Variable(true);
|
|
||||||
|
|
||||||
FullscreenState.connect('changed', (v) => {
|
|
||||||
BarVisible.setValue(!v.value.monitors.includes(monitor));
|
|
||||||
});
|
|
||||||
|
|
||||||
const barCloser = Window({
|
|
||||||
name: `bar-${monitor}-closer`,
|
|
||||||
visible: false,
|
|
||||||
gdkmonitor,
|
|
||||||
anchor: ['top', 'bottom', 'left', 'right'],
|
|
||||||
layer: 'overlay',
|
|
||||||
|
|
||||||
child: EventBox({
|
|
||||||
on_hover: () => {
|
|
||||||
barCloser.set_visible(false);
|
|
||||||
BarVisible.setValue(false);
|
|
||||||
},
|
|
||||||
|
|
||||||
child: Box({
|
|
||||||
css: 'padding: 1px;',
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
// Hide bar instantly when out of focus
|
|
||||||
Hyprland.active.workspace.connect('changed', () => {
|
|
||||||
const addr = FullscreenState.value.clientAddrs.get(monitor);
|
|
||||||
|
|
||||||
if (addr) {
|
|
||||||
const client = Hyprland.getClient(addr);
|
|
||||||
|
|
||||||
if (client!.workspace.id !== Hyprland.active.workspace.id) {
|
|
||||||
BarVisible.setValue(false);
|
|
||||||
barCloser.visible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const buffer = Box({
|
|
||||||
css: 'min-height: 10px',
|
|
||||||
visible: BarVisible.bind().as((v) => !v),
|
|
||||||
});
|
|
||||||
|
|
||||||
const vertical = anchor.includes('left') && anchor.includes('right');
|
|
||||||
const isBottomOrLeft = (
|
|
||||||
anchor.includes('left') && anchor.includes('right') && anchor.includes('bottom')
|
|
||||||
) || (
|
|
||||||
anchor.includes('top') && anchor.includes('bottom') && anchor.includes('left')
|
|
||||||
);
|
|
||||||
|
|
||||||
let transition: 'slide_up' | 'slide_down' | 'slide_left' | 'slide_right';
|
|
||||||
|
|
||||||
if (vertical) {
|
|
||||||
transition = isBottomOrLeft ? 'slide_up' : 'slide_down';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
transition = isBottomOrLeft ? 'slide_right' : 'slide_left';
|
|
||||||
}
|
|
||||||
|
|
||||||
const barWrap = Revealer({
|
|
||||||
reveal_child: BarVisible.bind(),
|
|
||||||
transition,
|
|
||||||
child: bar,
|
|
||||||
});
|
|
||||||
|
|
||||||
return Window({
|
|
||||||
name: `bar-${monitor}`,
|
|
||||||
layer: 'overlay',
|
|
||||||
gdkmonitor,
|
|
||||||
margins: [-1, -1, -1, -1],
|
|
||||||
anchor,
|
|
||||||
...rest,
|
|
||||||
|
|
||||||
attribute: {
|
|
||||||
barCloser,
|
|
||||||
},
|
|
||||||
|
|
||||||
child: EventBox({
|
|
||||||
child: Box({
|
|
||||||
css: 'min-height: 1px; padding: 1px;',
|
|
||||||
hexpand: true,
|
|
||||||
hpack: 'fill',
|
|
||||||
vertical,
|
|
||||||
|
|
||||||
children: isBottomOrLeft ?
|
|
||||||
[buffer, barWrap] :
|
|
||||||
[barWrap, buffer],
|
|
||||||
}),
|
|
||||||
}).on('enter-notify-event', () => {
|
|
||||||
if (!BarVisible.value) {
|
|
||||||
barCloser.visible = true;
|
|
||||||
BarVisible.setValue(true);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,21 +0,0 @@
|
||||||
const Audio = await Service.import('audio');
|
|
||||||
const { Label, Icon } = Widget;
|
|
||||||
|
|
||||||
import { SpeakerIcon } from '../../misc/audio-icons.ts';
|
|
||||||
import HoverRevealer from './hover-revealer.ts';
|
|
||||||
|
|
||||||
|
|
||||||
export default () => HoverRevealer({
|
|
||||||
class_name: 'audio',
|
|
||||||
|
|
||||||
icon: Icon({
|
|
||||||
icon: SpeakerIcon.bind(),
|
|
||||||
}),
|
|
||||||
|
|
||||||
label: Label().hook(Audio, (self) => {
|
|
||||||
if (Audio.speaker.volume) {
|
|
||||||
self.label =
|
|
||||||
`${Math.round(Audio.speaker.volume * 100)}%`;
|
|
||||||
}
|
|
||||||
}, 'speaker-changed'),
|
|
||||||
});
|
|
|
@ -1,26 +0,0 @@
|
||||||
const Bluetooth = await Service.import('bluetooth');
|
|
||||||
const { Label, Icon } = Widget;
|
|
||||||
|
|
||||||
import HoverRevealer from './hover-revealer.ts';
|
|
||||||
|
|
||||||
|
|
||||||
export default () => HoverRevealer({
|
|
||||||
class_name: 'bluetooth',
|
|
||||||
|
|
||||||
icon: Icon().hook(Bluetooth, (self) => {
|
|
||||||
if (Bluetooth.enabled) {
|
|
||||||
self.icon = Bluetooth.connected_devices[0] ?
|
|
||||||
Bluetooth.connected_devices[0].icon_name :
|
|
||||||
'bluetooth-active-symbolic';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.icon = 'bluetooth-disabled-symbolic';
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
label: Label().hook(Bluetooth, (self) => {
|
|
||||||
self.label = Bluetooth.connected_devices[0] ?
|
|
||||||
`${Bluetooth.connected_devices[0]}` :
|
|
||||||
'Disconnected';
|
|
||||||
}, 'notify::connected-devices'),
|
|
||||||
});
|
|
|
@ -1,17 +0,0 @@
|
||||||
const { Icon, Label } = Widget;
|
|
||||||
|
|
||||||
import Brightness from '../../../services/brightness.ts';
|
|
||||||
import HoverRevealer from './hover-revealer.ts';
|
|
||||||
|
|
||||||
|
|
||||||
export default () => HoverRevealer({
|
|
||||||
class_name: 'brightness',
|
|
||||||
|
|
||||||
icon: Icon({
|
|
||||||
icon: Brightness.bind('screenIcon'),
|
|
||||||
}),
|
|
||||||
|
|
||||||
label: Label().hook(Brightness, (self) => {
|
|
||||||
self.label = `${Math.round(Brightness.screen * 100)}%`;
|
|
||||||
}, 'screen'),
|
|
||||||
});
|
|
|
@ -1,48 +0,0 @@
|
||||||
const { Box, Revealer } = Widget;
|
|
||||||
|
|
||||||
import Gtk from 'gi://Gtk?version=3.0';
|
|
||||||
|
|
||||||
import Separator from '../../misc/separator.ts';
|
|
||||||
import CursorBox from '../../misc/cursorbox.ts';
|
|
||||||
|
|
||||||
|
|
||||||
export default ({
|
|
||||||
class_name,
|
|
||||||
icon,
|
|
||||||
label,
|
|
||||||
spacing = 5,
|
|
||||||
}) => {
|
|
||||||
const hoverRevLabel = Revealer({
|
|
||||||
transition: 'slide_right',
|
|
||||||
attribute: {
|
|
||||||
var: Variable(Box()),
|
|
||||||
},
|
|
||||||
|
|
||||||
child: Box({
|
|
||||||
|
|
||||||
children: [
|
|
||||||
Separator(spacing),
|
|
||||||
|
|
||||||
label,
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const widget = CursorBox({
|
|
||||||
on_hover: () => {
|
|
||||||
hoverRevLabel.reveal_child = true;
|
|
||||||
hoverRevLabel.attribute.var.value.set_state_flags(Gtk.StateFlags.PRELIGHT, false);
|
|
||||||
},
|
|
||||||
|
|
||||||
child: Box({
|
|
||||||
class_name,
|
|
||||||
|
|
||||||
children: [
|
|
||||||
icon,
|
|
||||||
hoverRevLabel,
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
return widget;
|
|
||||||
};
|
|
|
@ -1,37 +0,0 @@
|
||||||
const Network = await Service.import('network');
|
|
||||||
const { Label, Icon } = Widget;
|
|
||||||
|
|
||||||
import HoverRevealer from './hover-revealer.ts';
|
|
||||||
|
|
||||||
|
|
||||||
export default () => HoverRevealer({
|
|
||||||
class_name: 'network',
|
|
||||||
|
|
||||||
icon: Icon().hook(Network, (self) => {
|
|
||||||
if (Network.wifi.internet === 'connected' ||
|
|
||||||
Network.wifi.internet === 'connecting') {
|
|
||||||
self.icon = Network.wifi.icon_name;
|
|
||||||
}
|
|
||||||
else if (Network.wired.internet === 'connected' ||
|
|
||||||
Network.wired.internet === 'connecting') {
|
|
||||||
self.icon = Network.wired.icon_name;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.icon = Network.wifi.icon_name;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
label: Label().hook(Network, (self) => {
|
|
||||||
if (Network.wifi.internet === 'connected' ||
|
|
||||||
Network.wifi.internet === 'connecting') {
|
|
||||||
self.label = Network.wifi.ssid || 'Unknown';
|
|
||||||
}
|
|
||||||
else if (Network.wired.internet === 'connected' ||
|
|
||||||
Network.wired.internet === 'connecting') {
|
|
||||||
self.label = 'Connected';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.label = 'Disconnected';
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
});
|
|
|
@ -1,30 +0,0 @@
|
||||||
const Battery = await Service.import('battery');
|
|
||||||
const { Label, Icon, Box } = Widget;
|
|
||||||
|
|
||||||
import Separator from '../../misc/separator.ts';
|
|
||||||
|
|
||||||
const LOW_BATT = 20;
|
|
||||||
const SPACING = 5;
|
|
||||||
|
|
||||||
|
|
||||||
export default () => Box({
|
|
||||||
class_name: 'toggle-off battery',
|
|
||||||
|
|
||||||
children: [
|
|
||||||
Icon({
|
|
||||||
class_name: 'battery-indicator',
|
|
||||||
icon: Battery.bind('icon_name'),
|
|
||||||
}).hook(Battery, (self) => {
|
|
||||||
self.toggleClassName('charging', Battery.charging);
|
|
||||||
self.toggleClassName('charged', Battery.charged);
|
|
||||||
self.toggleClassName('low', Battery.percent < LOW_BATT);
|
|
||||||
}),
|
|
||||||
|
|
||||||
Separator(SPACING),
|
|
||||||
|
|
||||||
Label({
|
|
||||||
label: Battery.bind('percent')
|
|
||||||
.transform((v) => `${v}%`),
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
});
|
|
|
@ -1,19 +0,0 @@
|
||||||
import CursorBox from '../../misc/cursorbox.ts';
|
|
||||||
import Clock from './clock';
|
|
||||||
|
|
||||||
|
|
||||||
export default () => CursorBox({
|
|
||||||
class_name: 'toggle-off',
|
|
||||||
|
|
||||||
on_primary_click_release: () => App.toggleWindow('win-calendar'),
|
|
||||||
|
|
||||||
setup: (self) => {
|
|
||||||
self.hook(App, (_, windowName, visible) => {
|
|
||||||
if (windowName === 'win-calendar') {
|
|
||||||
self.toggleClassName('toggle-on', visible);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
child: Clock(),
|
|
||||||
});
|
|
|
@ -1,23 +0,0 @@
|
||||||
const { Label } = Widget;
|
|
||||||
const { new_now_local } = imports.gi.GLib.DateTime;
|
|
||||||
|
|
||||||
|
|
||||||
export default () => Label({ class_name: 'clock' })
|
|
||||||
.poll(1000, (self) => {
|
|
||||||
const time = new_now_local();
|
|
||||||
|
|
||||||
const dayName = time.format('%a. ');
|
|
||||||
const dayNum = time.get_day_of_month();
|
|
||||||
const date = time.format(' %b. ');
|
|
||||||
const hour = (new Date().toLocaleString([], {
|
|
||||||
hour: 'numeric',
|
|
||||||
minute: 'numeric',
|
|
||||||
hour12: true,
|
|
||||||
}) ?? '')
|
|
||||||
.replace('a.m.', 'AM')
|
|
||||||
.replace('p.m.', 'PM');
|
|
||||||
|
|
||||||
if (dayNum && dayName && date) {
|
|
||||||
self.label = dayName + dayNum + date + hour;
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,33 +0,0 @@
|
||||||
const Applications = await Service.import('applications');
|
|
||||||
const Hyprland = await Service.import('hyprland');
|
|
||||||
const { Box, Icon, Label } = Widget;
|
|
||||||
|
|
||||||
import Separator from '../../misc/separator.ts';
|
|
||||||
|
|
||||||
const SPACING = 8;
|
|
||||||
|
|
||||||
|
|
||||||
export default () => Box({
|
|
||||||
class_name: 'current-window',
|
|
||||||
|
|
||||||
children: [
|
|
||||||
Separator(SPACING / 2),
|
|
||||||
|
|
||||||
Icon({ size: 30 })
|
|
||||||
.hook(Hyprland.active.client, (self) => {
|
|
||||||
const app = Applications
|
|
||||||
.query(Hyprland.active.client.class)[0];
|
|
||||||
|
|
||||||
self.icon = app?.icon_name || '';
|
|
||||||
}),
|
|
||||||
|
|
||||||
Separator(SPACING),
|
|
||||||
|
|
||||||
Label({
|
|
||||||
truncate: 'end',
|
|
||||||
label: Hyprland.active.client.bind('title'),
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
}).hook(Hyprland.active.client, (self) => {
|
|
||||||
self.visible = Hyprland.active.client.title !== '';
|
|
||||||
});
|
|
|
@ -1,60 +0,0 @@
|
||||||
const Notifications = await Service.import('notifications');
|
|
||||||
const { Box, CenterBox, Icon, Label } = Widget;
|
|
||||||
|
|
||||||
import CursorBox from '../../misc/cursorbox.ts';
|
|
||||||
import Separator from '../../misc/separator.ts';
|
|
||||||
|
|
||||||
const SPACING = 4;
|
|
||||||
|
|
||||||
// Types
|
|
||||||
import { PopupWindow } from 'global-types';
|
|
||||||
|
|
||||||
|
|
||||||
export default () => CursorBox({
|
|
||||||
class_name: 'toggle-off',
|
|
||||||
|
|
||||||
on_primary_click_release: (self) => {
|
|
||||||
(App.getWindow('win-notification-center') as PopupWindow)
|
|
||||||
.set_x_pos(
|
|
||||||
self.get_allocation(),
|
|
||||||
'right',
|
|
||||||
);
|
|
||||||
|
|
||||||
App.toggleWindow('win-notification-center');
|
|
||||||
},
|
|
||||||
|
|
||||||
setup: (self) => {
|
|
||||||
self.hook(App, (_, windowName, visible) => {
|
|
||||||
if (windowName === 'win-notification-center') {
|
|
||||||
self.toggleClassName('toggle-on', visible);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
child: CenterBox({
|
|
||||||
class_name: 'notif-panel',
|
|
||||||
|
|
||||||
center_widget: Box({
|
|
||||||
children: [
|
|
||||||
Icon().hook(Notifications, (self) => {
|
|
||||||
if (Notifications.dnd) {
|
|
||||||
self.icon = 'notification-disabled-symbolic';
|
|
||||||
}
|
|
||||||
else if (Notifications.notifications.length > 0) {
|
|
||||||
self.icon = 'notification-new-symbolic';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.icon = 'notification-symbolic';
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
Separator(SPACING),
|
|
||||||
|
|
||||||
Label({
|
|
||||||
label: Notifications.bind('notifications')
|
|
||||||
.transform((n) => String(n.length)),
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
});
|
|
|
@ -1,23 +0,0 @@
|
||||||
const { Label } = Widget;
|
|
||||||
|
|
||||||
import Tablet from '../../../services/tablet.ts';
|
|
||||||
import CursorBox from '../../misc/cursorbox.ts';
|
|
||||||
|
|
||||||
|
|
||||||
export default () => CursorBox({
|
|
||||||
class_name: 'toggle-off',
|
|
||||||
|
|
||||||
on_primary_click_release: () => Tablet.toggleOsk(),
|
|
||||||
|
|
||||||
setup: (self) => {
|
|
||||||
self.hook(Tablet, () => {
|
|
||||||
self.toggleClassName('toggle-on', Tablet.oskState);
|
|
||||||
}, 'osk-toggled');
|
|
||||||
},
|
|
||||||
|
|
||||||
child: Label({
|
|
||||||
class_name: 'osk-toggle',
|
|
||||||
xalign: 0.6,
|
|
||||||
label: ' ',
|
|
||||||
}),
|
|
||||||
});
|
|
|
@ -1,85 +0,0 @@
|
||||||
const { Box, Icon } = Widget;
|
|
||||||
|
|
||||||
import Audio from '../hovers/audio.ts';
|
|
||||||
import Bluetooth from '../hovers/bluetooth.ts';
|
|
||||||
import Brightness from '../hovers/brightness.ts';
|
|
||||||
import KeyboardLayout from '../hovers/keyboard-layout.ts';
|
|
||||||
import Network from '../hovers/network.ts';
|
|
||||||
|
|
||||||
import CursorBox from '../../misc/cursorbox.ts';
|
|
||||||
import Separator from '../../misc/separator.ts';
|
|
||||||
|
|
||||||
const SPACING = 4;
|
|
||||||
|
|
||||||
// Types
|
|
||||||
import { PopupWindow } from 'global-types';
|
|
||||||
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const hoverRevealers = [
|
|
||||||
KeyboardLayout(),
|
|
||||||
|
|
||||||
Brightness(),
|
|
||||||
|
|
||||||
Audio(),
|
|
||||||
|
|
||||||
Bluetooth(),
|
|
||||||
|
|
||||||
Network(),
|
|
||||||
];
|
|
||||||
|
|
||||||
const widget = CursorBox({
|
|
||||||
class_name: 'toggle-off',
|
|
||||||
|
|
||||||
on_primary_click_release: (self) => {
|
|
||||||
(App.getWindow('win-quick-settings') as PopupWindow)
|
|
||||||
.set_x_pos(
|
|
||||||
self.get_allocation(),
|
|
||||||
'right',
|
|
||||||
);
|
|
||||||
|
|
||||||
App.toggleWindow('win-quick-settings');
|
|
||||||
},
|
|
||||||
|
|
||||||
setup: (self) => {
|
|
||||||
self.hook(App, (_, windowName, visible) => {
|
|
||||||
if (windowName === 'win-quick-settings') {
|
|
||||||
self.toggleClassName('toggle-on', visible);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
attribute: {
|
|
||||||
hoverRevealers: hoverRevealers.map((rev) => {
|
|
||||||
const box = rev.child;
|
|
||||||
|
|
||||||
return box.children[1];
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
on_hover_lost: (self) => {
|
|
||||||
self.attribute.hoverRevealers.forEach((rev) => {
|
|
||||||
rev.reveal_child = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
child: Box({
|
|
||||||
class_name: 'quick-settings-toggle',
|
|
||||||
vertical: false,
|
|
||||||
children: [
|
|
||||||
Separator(SPACING),
|
|
||||||
|
|
||||||
...hoverRevealers,
|
|
||||||
|
|
||||||
Icon('nixos-logo-symbolic'),
|
|
||||||
|
|
||||||
Separator(SPACING),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
widget.attribute.hoverRevealers.forEach((hv) => {
|
|
||||||
hv.attribute.var.setValue(widget);
|
|
||||||
});
|
|
||||||
|
|
||||||
return widget;
|
|
||||||
};
|
|
|
@ -1,100 +0,0 @@
|
||||||
import AstalTray from 'gi://AstalTray?version=0.1';
|
|
||||||
const SystemTray = AstalTray.Tray.get_default();
|
|
||||||
|
|
||||||
|
|
||||||
const { timeout } = Utils;
|
|
||||||
const { Box, Icon, MenuItem, MenuBar, Revealer } = Widget;
|
|
||||||
|
|
||||||
import Separator from '../../misc/separator.ts';
|
|
||||||
|
|
||||||
const REVEAL_DURATION = 500;
|
|
||||||
const SPACING = 12;
|
|
||||||
|
|
||||||
|
|
||||||
const SysTrayItem = (item: AstalTray.TrayItem) => {
|
|
||||||
if (item.id === 'spotify-client') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MenuItem({
|
|
||||||
submenu: item.create_menu(),
|
|
||||||
child: Revealer({
|
|
||||||
transition: 'slide_right',
|
|
||||||
transition_duration: REVEAL_DURATION,
|
|
||||||
|
|
||||||
child: Icon({
|
|
||||||
size: 24,
|
|
||||||
icon: Utils.watch(
|
|
||||||
item.iconPixbuf || item.iconName || 'image-missing',
|
|
||||||
item,
|
|
||||||
() => item.iconPixbuf || item.iconName || 'image-missing',
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
}).bind('tooltip_markup', item, 'tooltipMarkup');
|
|
||||||
};
|
|
||||||
|
|
||||||
const SysTray = () => MenuBar({
|
|
||||||
attribute: { items: new Map() },
|
|
||||||
|
|
||||||
setup: (self) => {
|
|
||||||
self
|
|
||||||
.hook(SystemTray, (_, id) => {
|
|
||||||
if (!id) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const item = SystemTray.get_item(id);
|
|
||||||
|
|
||||||
if (self.attribute.items.has(id) || !item) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const w = SysTrayItem(item);
|
|
||||||
|
|
||||||
// Early return if item is in blocklist
|
|
||||||
if (!w) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.attribute.items.set(id, w);
|
|
||||||
self.add(w);
|
|
||||||
self.show_all();
|
|
||||||
|
|
||||||
w.child.reveal_child = true;
|
|
||||||
}, 'item_added')
|
|
||||||
|
|
||||||
.hook(SystemTray, (_, id) => {
|
|
||||||
if (!id || !self.attribute.items.has(id)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.attribute.items.get(id).child.reveal_child = false;
|
|
||||||
timeout(REVEAL_DURATION, () => {
|
|
||||||
self.attribute.items.get(id).destroy();
|
|
||||||
self.attribute.items.delete(id);
|
|
||||||
});
|
|
||||||
}, 'item_removed');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const systray = SysTray();
|
|
||||||
|
|
||||||
return Revealer({
|
|
||||||
transition: 'slide_right',
|
|
||||||
|
|
||||||
child: Box({
|
|
||||||
children: [
|
|
||||||
Box({
|
|
||||||
class_name: 'sys-tray',
|
|
||||||
children: [systray],
|
|
||||||
}),
|
|
||||||
|
|
||||||
Separator(SPACING),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
}).hook(SystemTray, (self) => {
|
|
||||||
self.reveal_child = systray.get_children().length > 0;
|
|
||||||
}, 'item_added');
|
|
||||||
};
|
|
|
@ -1,24 +0,0 @@
|
||||||
const { Box, Label } = Widget;
|
|
||||||
|
|
||||||
import Tablet from '../../../services/tablet.ts';
|
|
||||||
import CursorBox from '../../misc/cursorbox.ts';
|
|
||||||
|
|
||||||
|
|
||||||
export default () => CursorBox({
|
|
||||||
class_name: 'toggle-off',
|
|
||||||
|
|
||||||
on_primary_click_release: () => Tablet.toggleMode(),
|
|
||||||
|
|
||||||
setup: (self) => {
|
|
||||||
self.hook(Tablet, () => {
|
|
||||||
self.toggleClassName('toggle-on', Tablet.tabletMode);
|
|
||||||
}, 'mode-toggled');
|
|
||||||
},
|
|
||||||
|
|
||||||
child: Box({
|
|
||||||
class_name: 'tablet-toggle',
|
|
||||||
vertical: false,
|
|
||||||
children: [Label(' ')],
|
|
||||||
}),
|
|
||||||
|
|
||||||
});
|
|
|
@ -1,179 +0,0 @@
|
||||||
const Hyprland = await Service.import('hyprland');
|
|
||||||
|
|
||||||
const { timeout } = Utils;
|
|
||||||
const { Box, Overlay, Revealer } = Widget;
|
|
||||||
|
|
||||||
import CursorBox from '../../misc/cursorbox.ts';
|
|
||||||
|
|
||||||
const URGENT_DURATION = 1000;
|
|
||||||
|
|
||||||
// Types
|
|
||||||
import {
|
|
||||||
BoxGeneric,
|
|
||||||
EventBoxGeneric,
|
|
||||||
OverlayGeneric,
|
|
||||||
RevealerGeneric,
|
|
||||||
Workspace,
|
|
||||||
} from 'global-types';
|
|
||||||
|
|
||||||
|
|
||||||
const Workspace = ({ id }: { id: number }) => {
|
|
||||||
return Revealer({
|
|
||||||
transition: 'slide_right',
|
|
||||||
attribute: { id },
|
|
||||||
|
|
||||||
child: CursorBox({
|
|
||||||
tooltip_text: `${id}`,
|
|
||||||
|
|
||||||
on_primary_click_release: () => {
|
|
||||||
Hyprland.messageAsync(`dispatch workspace ${id}`);
|
|
||||||
},
|
|
||||||
|
|
||||||
child: Box({
|
|
||||||
vpack: 'center',
|
|
||||||
class_name: 'button',
|
|
||||||
|
|
||||||
setup: (self) => {
|
|
||||||
const update = (
|
|
||||||
_: BoxGeneric,
|
|
||||||
addr: string | undefined,
|
|
||||||
) => {
|
|
||||||
const workspace = Hyprland.getWorkspace(id);
|
|
||||||
const occupied = workspace && workspace.windows > 0;
|
|
||||||
|
|
||||||
self.toggleClassName('occupied', occupied);
|
|
||||||
|
|
||||||
if (!addr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deal with urgent windows
|
|
||||||
const client = Hyprland.getClient(addr);
|
|
||||||
const isThisUrgent = client &&
|
|
||||||
client.workspace.id === id;
|
|
||||||
|
|
||||||
if (isThisUrgent) {
|
|
||||||
self.toggleClassName('urgent', true);
|
|
||||||
|
|
||||||
// Only show for a sec when urgent is current workspace
|
|
||||||
if (Hyprland.active.workspace.id === id) {
|
|
||||||
timeout(URGENT_DURATION, () => {
|
|
||||||
self.toggleClassName('urgent', false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self
|
|
||||||
.hook(Hyprland, update)
|
|
||||||
|
|
||||||
// Deal with urgent windows
|
|
||||||
.hook(Hyprland, update, 'urgent-window')
|
|
||||||
|
|
||||||
.hook(Hyprland.active.workspace, () => {
|
|
||||||
if (Hyprland.active.workspace.id === id) {
|
|
||||||
self.toggleClassName('urgent', false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
const L_PADDING = 16;
|
|
||||||
const WS_WIDTH = 30;
|
|
||||||
|
|
||||||
const updateHighlight = (self: BoxGeneric) => {
|
|
||||||
const currentId = Hyprland.active.workspace.id;
|
|
||||||
|
|
||||||
const indicators = (((self.get_parent() as OverlayGeneric)
|
|
||||||
.child as EventBoxGeneric)
|
|
||||||
.child as BoxGeneric)
|
|
||||||
.children as Workspace[];
|
|
||||||
|
|
||||||
const currentIndex = indicators
|
|
||||||
.findIndex((w) => w.attribute.id === currentId);
|
|
||||||
|
|
||||||
if (currentIndex < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.setCss(`margin-left: ${L_PADDING + (currentIndex * WS_WIDTH)}px`);
|
|
||||||
};
|
|
||||||
|
|
||||||
const highlight = Box({
|
|
||||||
vpack: 'center',
|
|
||||||
hpack: 'start',
|
|
||||||
class_name: 'button active',
|
|
||||||
|
|
||||||
}).hook(Hyprland.active.workspace, updateHighlight);
|
|
||||||
|
|
||||||
const widget = Overlay({
|
|
||||||
pass_through: true,
|
|
||||||
overlays: [highlight],
|
|
||||||
child: CursorBox({
|
|
||||||
child: Box({
|
|
||||||
class_name: 'workspaces',
|
|
||||||
|
|
||||||
attribute: { workspaces: [] as Workspace[] },
|
|
||||||
|
|
||||||
setup: (self) => {
|
|
||||||
const refresh = () => {
|
|
||||||
(self.children as RevealerGeneric[])
|
|
||||||
.forEach((rev) => {
|
|
||||||
rev.reveal_child = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
self.attribute.workspaces
|
|
||||||
.forEach((ws) => {
|
|
||||||
ws.reveal_child = true;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateWorkspaces = () => {
|
|
||||||
Hyprland.workspaces.forEach((ws) => {
|
|
||||||
const currentWs =
|
|
||||||
(self.children as Workspace[])
|
|
||||||
.find((ch) => ch.attribute.id === ws.id);
|
|
||||||
|
|
||||||
if (!currentWs && ws.id > 0) {
|
|
||||||
self.add(Workspace({ id: ws.id }));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
self.show_all();
|
|
||||||
|
|
||||||
// Make sure the order is correct
|
|
||||||
self.attribute.workspaces.forEach((workspace, i) => {
|
|
||||||
(workspace.get_parent() as BoxGeneric)
|
|
||||||
.reorder_child(workspace, i);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
self.hook(Hyprland, () => {
|
|
||||||
self.attribute.workspaces =
|
|
||||||
(self.children as Workspace[])
|
|
||||||
.filter((ch) => {
|
|
||||||
return Hyprland.workspaces.find((ws) => {
|
|
||||||
return ws.id === ch.attribute.id;
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.sort((a, b) =>
|
|
||||||
a.attribute.id - b.attribute.id);
|
|
||||||
|
|
||||||
updateWorkspaces();
|
|
||||||
refresh();
|
|
||||||
|
|
||||||
// Make sure the highlight doesn't go too far
|
|
||||||
const TEMP_TIMEOUT = 10;
|
|
||||||
|
|
||||||
timeout(TEMP_TIMEOUT, () => updateHighlight(highlight));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
return widget;
|
|
||||||
};
|
|
|
@ -1,80 +0,0 @@
|
||||||
const { CenterBox, Box } = Widget;
|
|
||||||
|
|
||||||
import Separator from '../misc/separator.ts';
|
|
||||||
|
|
||||||
import Battery from './items/battery.ts';
|
|
||||||
import Clock from './items/cal-opener.ts';
|
|
||||||
import CurrentWindow from './items/current-window.ts';
|
|
||||||
import Heart from './items/heart.ts';
|
|
||||||
import NotifButton from './items/notif-button.ts';
|
|
||||||
import OskToggle from './items/osk-toggle.ts';
|
|
||||||
import QsToggle from './items/quick-settings.ts';
|
|
||||||
import SysTray from './items/systray.ts';
|
|
||||||
import TabletToggle from './items/tablet-toggle.ts';
|
|
||||||
import Workspaces from './items/workspaces.ts';
|
|
||||||
|
|
||||||
import BarRevealer from './fullscreen.ts';
|
|
||||||
|
|
||||||
const SPACING = 12;
|
|
||||||
|
|
||||||
|
|
||||||
export default () => BarRevealer({
|
|
||||||
anchor: ['top', 'left', 'right'],
|
|
||||||
exclusivity: 'exclusive',
|
|
||||||
bar: CenterBox({
|
|
||||||
css: 'margin: 5px 5px 5px 5px',
|
|
||||||
class_name: 'bar',
|
|
||||||
|
|
||||||
start_widget: Box({
|
|
||||||
hpack: 'start',
|
|
||||||
children: [
|
|
||||||
|
|
||||||
OskToggle(),
|
|
||||||
|
|
||||||
Separator(SPACING),
|
|
||||||
|
|
||||||
TabletToggle(),
|
|
||||||
|
|
||||||
Separator(SPACING),
|
|
||||||
|
|
||||||
SysTray(),
|
|
||||||
|
|
||||||
Workspaces(),
|
|
||||||
|
|
||||||
Separator(SPACING),
|
|
||||||
|
|
||||||
CurrentWindow(),
|
|
||||||
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
|
|
||||||
center_widget: Box({
|
|
||||||
children: [
|
|
||||||
Separator(SPACING),
|
|
||||||
|
|
||||||
Clock(),
|
|
||||||
|
|
||||||
Separator(SPACING),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
|
|
||||||
end_widget: Box({
|
|
||||||
hpack: 'end',
|
|
||||||
children: [
|
|
||||||
Heart(),
|
|
||||||
|
|
||||||
Separator(SPACING),
|
|
||||||
|
|
||||||
Battery(),
|
|
||||||
|
|
||||||
Separator(SPACING),
|
|
||||||
|
|
||||||
NotifButton(),
|
|
||||||
|
|
||||||
Separator(SPACING),
|
|
||||||
|
|
||||||
QsToggle(),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
});
|
|
|
@ -1,80 +0,0 @@
|
||||||
const { Box, Button, Icon, Label, Revealer } = Widget;
|
|
||||||
|
|
||||||
|
|
||||||
const ImageClip = (key: number, val: string) => Box({
|
|
||||||
class_name: 'item',
|
|
||||||
name: key.toString(),
|
|
||||||
|
|
||||||
child: Icon({
|
|
||||||
icon: val.replace('img:', ''),
|
|
||||||
size: 100 * 2,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const TextClip = (key: number, val: string) => {
|
|
||||||
const lines = val.split('\n');
|
|
||||||
|
|
||||||
if (lines.length <= 5) {
|
|
||||||
return Box({
|
|
||||||
class_name: 'item',
|
|
||||||
name: key.toString(),
|
|
||||||
|
|
||||||
child: Label({
|
|
||||||
label: val,
|
|
||||||
truncate: 'end',
|
|
||||||
max_width_chars: 100,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const revText = Revealer({
|
|
||||||
hpack: 'start',
|
|
||||||
child: Label({
|
|
||||||
label: lines.slice(2, lines.length).join('\n'),
|
|
||||||
truncate: 'end',
|
|
||||||
max_width_chars: 100,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
return Box({
|
|
||||||
class_name: 'item',
|
|
||||||
name: key.toString(),
|
|
||||||
|
|
||||||
vertical: true,
|
|
||||||
children: [
|
|
||||||
Label({
|
|
||||||
label: lines.slice(0, 2).join('\n'),
|
|
||||||
truncate: 'end',
|
|
||||||
max_width_chars: 100,
|
|
||||||
hpack: 'start',
|
|
||||||
}),
|
|
||||||
|
|
||||||
revText,
|
|
||||||
|
|
||||||
Button({
|
|
||||||
child: Icon({
|
|
||||||
class_name: 'down-arrow',
|
|
||||||
icon: 'down-large-symbolic',
|
|
||||||
size: 24,
|
|
||||||
}),
|
|
||||||
|
|
||||||
on_primary_click_release: (self) => {
|
|
||||||
const state = !revText.reveal_child;
|
|
||||||
|
|
||||||
revText.reveal_child = state;
|
|
||||||
|
|
||||||
self.child.setCss(`
|
|
||||||
-gtk-icon-transform: rotate(${state ? '180' : '0'}deg);
|
|
||||||
`);
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ({
|
|
||||||
key = 0,
|
|
||||||
isImage = false,
|
|
||||||
val = '',
|
|
||||||
}) => isImage ? ImageClip(key, val) : TextClip(key, val);
|
|
|
@ -1,85 +0,0 @@
|
||||||
import { Fzf, FzfResultItem } from 'fzf';
|
|
||||||
import Gtk from 'gi://Gtk?version=3.0';
|
|
||||||
import Clipboard from '../../services/clipboard.ts';
|
|
||||||
|
|
||||||
import SortedList from '../misc/sorted-list.ts';
|
|
||||||
|
|
||||||
import ClipWidget from './clip.ts';
|
|
||||||
|
|
||||||
|
|
||||||
const getKey = (r: Gtk.ListBoxRow): number => parseInt(r.get_child()?.name ?? '0');
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
let fzfResults = [] as FzfResultItem<[number, { clip: string, isImage: boolean }]>[];
|
|
||||||
|
|
||||||
return SortedList({
|
|
||||||
name: 'clipboard',
|
|
||||||
class_name: 'clipboard',
|
|
||||||
transition: 'slide top',
|
|
||||||
|
|
||||||
on_select: (r) => {
|
|
||||||
Clipboard.copyOldItem(getKey(r));
|
|
||||||
App.closeWindow('win-clipboard');
|
|
||||||
},
|
|
||||||
|
|
||||||
setup_list: (list, entry) => {
|
|
||||||
list.cursor = 'pointer';
|
|
||||||
|
|
||||||
const CONNECT_ID = Clipboard.connect('history-searched', () => {
|
|
||||||
// Do every clip that existed before this widget
|
|
||||||
Clipboard.clips.forEach((clip, key) => {
|
|
||||||
const widget = ClipWidget({ key, isImage: clip.isImage, val: clip.clip });
|
|
||||||
|
|
||||||
list.add(widget);
|
|
||||||
widget.show_all();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Setup connection for new clips
|
|
||||||
Clipboard.connect('clip-added', (_, [key, clip]) => {
|
|
||||||
const widget = ClipWidget({ key, isImage: clip.isImage, val: clip.clip });
|
|
||||||
|
|
||||||
list.add(widget);
|
|
||||||
widget.show_all();
|
|
||||||
});
|
|
||||||
|
|
||||||
list.set_sort_func((a, b) => {
|
|
||||||
if (entry.text === '' || entry.text === '-') {
|
|
||||||
a.set_visible(true);
|
|
||||||
b.set_visible(true);
|
|
||||||
|
|
||||||
return getKey(b) - getKey(a);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const ROW_1 = fzfResults.find((f) => f.item[0] === getKey(a))?.score ?? 0;
|
|
||||||
const ROW_2 = fzfResults.find((f) => f.item[0] === getKey(b))?.score ?? 0;
|
|
||||||
|
|
||||||
a.set_visible(ROW_1 !== 0);
|
|
||||||
b.set_visible(ROW_2 !== 0);
|
|
||||||
|
|
||||||
return ROW_2 - ROW_1;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Trigger on_text_change after init
|
|
||||||
entry.text = '-';
|
|
||||||
|
|
||||||
Clipboard.disconnect(CONNECT_ID);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
on_text_change: (text, list, placeholder) => {
|
|
||||||
const fzf = new Fzf([...Clipboard.clips.entries()], {
|
|
||||||
selector: ([_key, { clip }]) => clip,
|
|
||||||
|
|
||||||
tiebreakers: [(a, b) => b[0] - a[0]],
|
|
||||||
});
|
|
||||||
|
|
||||||
fzfResults = fzf.find(text);
|
|
||||||
list.invalidate_sort();
|
|
||||||
|
|
||||||
const visibleApps = list.get_children().filter((row) => row.visible).length;
|
|
||||||
|
|
||||||
placeholder.reveal_child = visibleApps <= 0;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,52 +0,0 @@
|
||||||
const { Window } = Widget;
|
|
||||||
|
|
||||||
import RoundedCorner from './screen-corners.ts';
|
|
||||||
|
|
||||||
|
|
||||||
const TopLeft = () => Window({
|
|
||||||
name: 'cornertl',
|
|
||||||
layer: 'overlay',
|
|
||||||
exclusivity: 'ignore',
|
|
||||||
anchor: ['top', 'left'],
|
|
||||||
visible: true,
|
|
||||||
click_through: true,
|
|
||||||
child: RoundedCorner('topleft'),
|
|
||||||
});
|
|
||||||
|
|
||||||
const TopRight = () => Window({
|
|
||||||
name: 'cornertr',
|
|
||||||
layer: 'overlay',
|
|
||||||
exclusivity: 'ignore',
|
|
||||||
anchor: ['top', 'right'],
|
|
||||||
visible: true,
|
|
||||||
click_through: true,
|
|
||||||
child: RoundedCorner('topright'),
|
|
||||||
});
|
|
||||||
|
|
||||||
const BottomLeft = () => Window({
|
|
||||||
name: 'cornerbl',
|
|
||||||
layer: 'overlay',
|
|
||||||
exclusivity: 'ignore',
|
|
||||||
anchor: ['bottom', 'left'],
|
|
||||||
visible: true,
|
|
||||||
click_through: true,
|
|
||||||
child: RoundedCorner('bottomleft'),
|
|
||||||
});
|
|
||||||
|
|
||||||
const BottomRight = () => Window({
|
|
||||||
name: 'cornerbr',
|
|
||||||
layer: 'overlay',
|
|
||||||
exclusivity: 'ignore',
|
|
||||||
anchor: ['bottom', 'right'],
|
|
||||||
visible: true,
|
|
||||||
click_through: true,
|
|
||||||
child: RoundedCorner('bottomright'),
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export default () => [
|
|
||||||
TopLeft(),
|
|
||||||
TopRight(),
|
|
||||||
BottomLeft(),
|
|
||||||
BottomRight(),
|
|
||||||
];
|
|
|
@ -1,79 +0,0 @@
|
||||||
const { Box, DrawingArea } = Widget;
|
|
||||||
|
|
||||||
const { Gtk } = imports.gi;
|
|
||||||
|
|
||||||
export default (
|
|
||||||
place = 'top left',
|
|
||||||
css = 'background-color: black;',
|
|
||||||
) => Box({
|
|
||||||
hpack: place.includes('left') ? 'start' : 'end',
|
|
||||||
vpack: place.includes('top') ? 'start' : 'end',
|
|
||||||
css: `
|
|
||||||
padding: 1px; margin:
|
|
||||||
${place.includes('top') ? '-1px' : '0'}
|
|
||||||
${place.includes('right') ? '-1px' : '0'}
|
|
||||||
${place.includes('bottom') ? '-1px' : '0'}
|
|
||||||
${place.includes('left') ? '-1px' : '0'};
|
|
||||||
`,
|
|
||||||
child: DrawingArea({
|
|
||||||
css: `
|
|
||||||
border-radius: 18px;
|
|
||||||
border-width: 0.068rem;
|
|
||||||
${css}
|
|
||||||
`,
|
|
||||||
setup: (widget) => {
|
|
||||||
let r = widget.get_style_context()
|
|
||||||
.get_property('border-radius', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
widget.set_size_request(r, r);
|
|
||||||
widget.connect('draw', (_, cr) => {
|
|
||||||
const c = widget.get_style_context()
|
|
||||||
.get_property('background-color', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
r = widget.get_style_context()
|
|
||||||
.get_property('border-radius', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
const borderColor = widget.get_style_context()
|
|
||||||
.get_property('color', Gtk.StateFlags.NORMAL);
|
|
||||||
|
|
||||||
// You're going to write border-width: something anyway
|
|
||||||
const borderWidth = widget.get_style_context()
|
|
||||||
.get_border(Gtk.StateFlags.NORMAL).left;
|
|
||||||
|
|
||||||
widget.set_size_request(r, r);
|
|
||||||
|
|
||||||
switch (place) {
|
|
||||||
case 'topleft':
|
|
||||||
cr.arc(r, r, r, Math.PI, 3 * Math.PI / 2);
|
|
||||||
cr.lineTo(0, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'topright':
|
|
||||||
cr.arc(0, r, r, 3 * Math.PI / 2, 2 * Math.PI);
|
|
||||||
cr.lineTo(r, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'bottomleft':
|
|
||||||
cr.arc(r, 0, r, Math.PI / 2, Math.PI);
|
|
||||||
cr.lineTo(0, r);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'bottomright':
|
|
||||||
cr.arc(0, 0, r, 0, Math.PI / 2);
|
|
||||||
cr.lineTo(r, r);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
cr.closePath();
|
|
||||||
cr.setSourceRGBA(c.red, c.green, c.blue, c.alpha);
|
|
||||||
cr.fill();
|
|
||||||
cr.setLineWidth(borderWidth);
|
|
||||||
cr.setSourceRGBA(borderColor.red,
|
|
||||||
borderColor.green,
|
|
||||||
borderColor.blue,
|
|
||||||
borderColor.alpha);
|
|
||||||
cr.stroke();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
});
|
|
|
@ -1,16 +0,0 @@
|
||||||
import PopupWindow from '../misc/popup.ts';
|
|
||||||
import CalendarWidget from './main.ts';
|
|
||||||
import { get_gdkmonitor_from_desc } from '../lib.ts';
|
|
||||||
|
|
||||||
|
|
||||||
const RIGHT_MARGIN = 20;
|
|
||||||
|
|
||||||
export default () => PopupWindow({
|
|
||||||
name: 'calendar',
|
|
||||||
anchor: ['bottom', 'right'],
|
|
||||||
margins: [0, RIGHT_MARGIN, 0, 0],
|
|
||||||
transition: 'slide bottom',
|
|
||||||
gdkmonitor: get_gdkmonitor_from_desc('desc:Acer Technologies Acer K212HQL T3EAA0014201'),
|
|
||||||
|
|
||||||
child: CalendarWidget(),
|
|
||||||
});
|
|
|
@ -1,92 +0,0 @@
|
||||||
const { Box, Calendar, Label } = Widget;
|
|
||||||
|
|
||||||
const { new_now_local } = imports.gi.GLib.DateTime;
|
|
||||||
|
|
||||||
|
|
||||||
const Divider = () => Box({
|
|
||||||
class_name: 'divider',
|
|
||||||
vertical: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const Time = () => Box({
|
|
||||||
class_name: 'timebox',
|
|
||||||
vertical: true,
|
|
||||||
|
|
||||||
children: [
|
|
||||||
Box({
|
|
||||||
class_name: 'time-container',
|
|
||||||
hpack: 'center',
|
|
||||||
vpack: 'center',
|
|
||||||
|
|
||||||
children: [
|
|
||||||
Label({
|
|
||||||
class_name: 'content',
|
|
||||||
label: 'hour',
|
|
||||||
setup: (self) => {
|
|
||||||
self.poll(1000, () => {
|
|
||||||
self.label = new_now_local().format('%H') || '';
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
|
|
||||||
Divider(),
|
|
||||||
|
|
||||||
Label({
|
|
||||||
class_name: 'content',
|
|
||||||
label: 'minute',
|
|
||||||
setup: (self) => {
|
|
||||||
self.poll(1000, () => {
|
|
||||||
self.label = new_now_local().format('%M') || '';
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
|
|
||||||
Box({
|
|
||||||
class_name: 'date-container',
|
|
||||||
hpack: 'center',
|
|
||||||
|
|
||||||
child: Label({
|
|
||||||
css: 'font-size: 20px',
|
|
||||||
label: 'complete date',
|
|
||||||
|
|
||||||
setup: (self) => {
|
|
||||||
self.poll(1000, () => {
|
|
||||||
const time = new_now_local();
|
|
||||||
|
|
||||||
const dayNameMonth = time.format('%A, %B ');
|
|
||||||
const dayNum = time.get_day_of_month();
|
|
||||||
const date = time.format(', %Y');
|
|
||||||
|
|
||||||
if (dayNum && dayNameMonth && date) {
|
|
||||||
self.label = dayNameMonth + dayNum + date;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
const CalendarWidget = () => Box({
|
|
||||||
class_name: 'cal-box',
|
|
||||||
|
|
||||||
child: Calendar({
|
|
||||||
show_day_names: true,
|
|
||||||
show_heading: true,
|
|
||||||
class_name: 'cal',
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
export default () => Box({
|
|
||||||
class_name: 'date',
|
|
||||||
vertical: true,
|
|
||||||
|
|
||||||
children: [
|
|
||||||
Time(),
|
|
||||||
CalendarWidget(),
|
|
||||||
],
|
|
||||||
});
|
|
|
@ -1,12 +0,0 @@
|
||||||
import PopupWindow from '../misc/popup.ts';
|
|
||||||
import CalendarWidget from './main.ts';
|
|
||||||
|
|
||||||
const TOP_MARGIN = 6;
|
|
||||||
|
|
||||||
export default () => PopupWindow({
|
|
||||||
name: 'calendar',
|
|
||||||
anchor: ['top'],
|
|
||||||
margins: [TOP_MARGIN, 0, 0, 0],
|
|
||||||
|
|
||||||
child: CalendarWidget(),
|
|
||||||
});
|
|
|
@ -1,43 +0,0 @@
|
||||||
const Hyprland = await Service.import('hyprland');
|
|
||||||
|
|
||||||
import Gdk from 'gi://Gdk?version=3.0';
|
|
||||||
|
|
||||||
/* Types */
|
|
||||||
import { Monitor } from 'types/service/hyprland';
|
|
||||||
|
|
||||||
|
|
||||||
export const get_hyprland_monitor = (monitor: Gdk.Monitor): Monitor | undefined => {
|
|
||||||
const manufacturer = monitor.manufacturer?.replace(',', '');
|
|
||||||
const model = monitor.model?.replace(',', '');
|
|
||||||
const start = `${manufacturer} ${model}`;
|
|
||||||
|
|
||||||
return Hyprland.monitors.find((m) => m.description.startsWith(start));
|
|
||||||
};
|
|
||||||
|
|
||||||
export const get_hyprland_monitor_desc = (monitor: Gdk.Monitor): string => {
|
|
||||||
const manufacturer = monitor.manufacturer?.replace(',', '');
|
|
||||||
const model = monitor.model?.replace(',', '');
|
|
||||||
const start = `${manufacturer} ${model}`;
|
|
||||||
|
|
||||||
return `desc:${Hyprland.monitors.find((m) => m.description.startsWith(start))?.description}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const get_gdkmonitor_from_desc = (desc: string): Gdk.Monitor => {
|
|
||||||
const display = Gdk.Display.get_default();
|
|
||||||
|
|
||||||
for (let m = 0; m < (display?.get_n_monitors() ?? 0); m++) {
|
|
||||||
const monitor = display?.get_monitor(m);
|
|
||||||
|
|
||||||
if (monitor && desc === get_hyprland_monitor_desc(monitor)) {
|
|
||||||
return monitor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw Error(`Monitor ${desc} not found`);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const get_monitor_desc_from_id = (id: number): string => {
|
|
||||||
const monitor = Hyprland.monitors.find((m) => m.id === id);
|
|
||||||
|
|
||||||
return `desc:${monitor?.description}`;
|
|
||||||
};
|
|
|
@ -1,211 +0,0 @@
|
||||||
const { Box, Entry, Label, Window } = Widget;
|
|
||||||
|
|
||||||
import Gdk from 'gi://Gdk?version=3.0';
|
|
||||||
import Gtk from 'gi://Gtk?version=3.0';
|
|
||||||
import Lock from 'gi://GtkSessionLock?version=0.1';
|
|
||||||
|
|
||||||
// This file is generated by Nix
|
|
||||||
import Vars from './vars.ts';
|
|
||||||
|
|
||||||
import Separator from '../misc/separator.ts';
|
|
||||||
import { get_hyprland_monitor_desc } from '../lib.ts';
|
|
||||||
|
|
||||||
/* Types */
|
|
||||||
import { Box as AgsBox } from 'types/widgets/box';
|
|
||||||
|
|
||||||
|
|
||||||
const lock = Lock.prepare_lock();
|
|
||||||
const windows = new Map<Gdk.Monitor, Gtk.Window>();
|
|
||||||
const blurBGs: AgsBox<Gtk.Widget, { geometry: { w: number, h: number } }>[] = [];
|
|
||||||
|
|
||||||
const transition_duration = 1000;
|
|
||||||
const WINDOW_MARGINS = -2;
|
|
||||||
const ENTRY_SPACING = 20;
|
|
||||||
const CLOCK_SPACING = 60;
|
|
||||||
|
|
||||||
const bgCSS = ({ w = 1, h = 1 } = {}) => `
|
|
||||||
border: 2px solid rgba(189, 147, 249, 0.8);
|
|
||||||
background: rgba(0, 0, 0, 0.2);
|
|
||||||
min-height: ${h}px;
|
|
||||||
min-width: ${w}px;
|
|
||||||
transition: min-height ${transition_duration / 2}ms,
|
|
||||||
min-width ${transition_duration / 2}ms;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const unlock = () => {
|
|
||||||
blurBGs.forEach((b) => {
|
|
||||||
b.css = bgCSS({
|
|
||||||
w: b.attribute.geometry.w,
|
|
||||||
h: 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
Utils.timeout(transition_duration / 2, () => {
|
|
||||||
b.css = bgCSS({
|
|
||||||
w: 1,
|
|
||||||
h: 1,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Utils.timeout(transition_duration, () => {
|
|
||||||
lock.unlock_and_destroy();
|
|
||||||
Gdk.Display.get_default()?.sync();
|
|
||||||
App.quit();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const Clock = () => Label({ class_name: 'clock' })
|
|
||||||
.poll(1000, (self) => {
|
|
||||||
self.label = (new Date().toLocaleString([], {
|
|
||||||
hour: 'numeric',
|
|
||||||
minute: 'numeric',
|
|
||||||
hour12: true,
|
|
||||||
}) ?? '')
|
|
||||||
.replace('a.m.', 'AM')
|
|
||||||
.replace('p.m.', 'PM');
|
|
||||||
});
|
|
||||||
|
|
||||||
const PasswordPrompt = (monitor: Gdk.Monitor, visible: boolean) => {
|
|
||||||
const rev = Box({
|
|
||||||
css: bgCSS(),
|
|
||||||
attribute: {
|
|
||||||
geometry: {} as { w: number, h: number },
|
|
||||||
},
|
|
||||||
|
|
||||||
setup: (self) => Utils.idle(() => {
|
|
||||||
self.attribute.geometry = {
|
|
||||||
w: monitor.geometry.width,
|
|
||||||
h: monitor.geometry.height,
|
|
||||||
};
|
|
||||||
|
|
||||||
self.css = bgCSS({
|
|
||||||
w: self.attribute.geometry.w,
|
|
||||||
h: 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
Utils.timeout(transition_duration / 2, () => {
|
|
||||||
self.css = bgCSS({
|
|
||||||
w: self.attribute.geometry.w,
|
|
||||||
h: self.attribute.geometry.h,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
blurBGs.push(rev);
|
|
||||||
|
|
||||||
Window({
|
|
||||||
name: `blur-bg-${monitor.get_model()}`,
|
|
||||||
gdkmonitor: monitor,
|
|
||||||
layer: 'overlay',
|
|
||||||
anchor: ['top', 'bottom', 'right', 'left'],
|
|
||||||
margins: [WINDOW_MARGINS],
|
|
||||||
exclusivity: 'ignore',
|
|
||||||
|
|
||||||
child: Box({
|
|
||||||
hexpand: false,
|
|
||||||
vexpand: false,
|
|
||||||
hpack: 'center',
|
|
||||||
vpack: 'center',
|
|
||||||
child: rev,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const label = Label('Enter password:');
|
|
||||||
|
|
||||||
return new Gtk.Window({
|
|
||||||
child: visible ?
|
|
||||||
Box({
|
|
||||||
vertical: true,
|
|
||||||
vpack: 'center',
|
|
||||||
hpack: 'center',
|
|
||||||
spacing: 16,
|
|
||||||
|
|
||||||
children: [
|
|
||||||
Clock(),
|
|
||||||
|
|
||||||
Separator(CLOCK_SPACING, { vertical: true }),
|
|
||||||
|
|
||||||
Box({
|
|
||||||
hpack: 'center',
|
|
||||||
class_name: 'avatar',
|
|
||||||
}),
|
|
||||||
|
|
||||||
Box({
|
|
||||||
class_name: 'entry-box',
|
|
||||||
vertical: true,
|
|
||||||
children: [
|
|
||||||
label,
|
|
||||||
|
|
||||||
Separator(ENTRY_SPACING, { vertical: true }),
|
|
||||||
|
|
||||||
Entry({
|
|
||||||
hpack: 'center',
|
|
||||||
xalign: 0.5,
|
|
||||||
visibility: false,
|
|
||||||
placeholder_text: 'password',
|
|
||||||
|
|
||||||
on_accept: (self) => {
|
|
||||||
self.sensitive = false;
|
|
||||||
|
|
||||||
Utils.authenticate(self.text ?? '')
|
|
||||||
.then(() => unlock())
|
|
||||||
.catch((e) => {
|
|
||||||
self.text = '';
|
|
||||||
label.label = e.message;
|
|
||||||
self.sensitive = true;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}).on('realize', (entry) => entry.grab_focus()),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
}) :
|
|
||||||
Box(),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const createWindow = (monitor: Gdk.Monitor) => {
|
|
||||||
const hyprDesc = get_hyprland_monitor_desc(monitor);
|
|
||||||
const entryVisible = Vars.mainMonitor === hyprDesc || Vars.dupeLockscreen;
|
|
||||||
const win = PasswordPrompt(monitor, entryVisible);
|
|
||||||
|
|
||||||
windows.set(monitor, win);
|
|
||||||
};
|
|
||||||
|
|
||||||
const lock_screen = () => {
|
|
||||||
const display = Gdk.Display.get_default();
|
|
||||||
|
|
||||||
for (let m = 0; m < (display?.get_n_monitors() ?? 0); m++) {
|
|
||||||
const monitor = display?.get_monitor(m);
|
|
||||||
|
|
||||||
if (monitor) {
|
|
||||||
createWindow(monitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
display?.connect('monitor-added', (_, monitor) => {
|
|
||||||
createWindow(monitor);
|
|
||||||
});
|
|
||||||
lock.lock_lock();
|
|
||||||
windows.forEach((win, monitor) => {
|
|
||||||
lock.new_surface(win, monitor);
|
|
||||||
win.show();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const on_finished = () => {
|
|
||||||
lock.destroy();
|
|
||||||
Gdk.Display.get_default()?.sync();
|
|
||||||
App.quit();
|
|
||||||
};
|
|
||||||
|
|
||||||
lock.connect('finished', on_finished);
|
|
||||||
|
|
||||||
if (Vars.hasFprintd) {
|
|
||||||
globalThis.authFinger = () => Utils.authenticate('')
|
|
||||||
.then(() => unlock())
|
|
||||||
.catch(logError);
|
|
||||||
globalThis.authFinger();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default () => lock_screen();
|
|
|
@ -1,4 +0,0 @@
|
||||||
import LaunchLockscreen from './lock.ts';
|
|
||||||
|
|
||||||
|
|
||||||
LaunchLockscreen();
|
|
|
@ -1,57 +0,0 @@
|
||||||
const Audio = await Service.import('audio');
|
|
||||||
|
|
||||||
const speakerIcons = {
|
|
||||||
101: 'audio-volume-overamplified-symbolic',
|
|
||||||
67: 'audio-volume-high-symbolic',
|
|
||||||
34: 'audio-volume-medium-symbolic',
|
|
||||||
1: 'audio-volume-low-symbolic',
|
|
||||||
0: 'audio-volume-muted-symbolic',
|
|
||||||
};
|
|
||||||
|
|
||||||
const micIcons = {
|
|
||||||
67: 'audio-input-microphone-high-symbolic',
|
|
||||||
34: 'audio-input-microphone-medium-symbolic',
|
|
||||||
1: 'audio-input-microphone-low-symbolic',
|
|
||||||
0: 'audio-input-microphone-muted-symbolic',
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
export const SpeakerIcon = Variable('');
|
|
||||||
Audio.connect('speaker-changed', () => {
|
|
||||||
if (!Audio.speaker) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Audio.speaker.stream?.is_muted) {
|
|
||||||
SpeakerIcon.setValue(speakerIcons[0]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const vol = Audio.speaker.volume * 100;
|
|
||||||
|
|
||||||
for (const threshold of [-1, 0, 33, 66, 100]) {
|
|
||||||
if (vol > threshold + 1) {
|
|
||||||
SpeakerIcon.setValue(speakerIcons[threshold + 1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export const MicIcon = Variable('');
|
|
||||||
Audio.connect('microphone-changed', () => {
|
|
||||||
if (!Audio.microphone) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Audio.microphone.stream?.is_muted) {
|
|
||||||
MicIcon.setValue(micIcons[0]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const vol = Audio.microphone.volume * 100;
|
|
||||||
|
|
||||||
for (const threshold of [-1, 0, 33, 66]) {
|
|
||||||
if (vol > threshold + 1) {
|
|
||||||
MicIcon.setValue(micIcons[threshold + 1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,15 +0,0 @@
|
||||||
const { Window } = Widget;
|
|
||||||
|
|
||||||
|
|
||||||
export default () => Window({
|
|
||||||
name: 'bg-gradient',
|
|
||||||
layer: 'background',
|
|
||||||
exclusivity: 'ignore',
|
|
||||||
anchor: ['top', 'bottom', 'left', 'right'],
|
|
||||||
css: `
|
|
||||||
background-image: -gtk-gradient (linear,
|
|
||||||
left top, left bottom,
|
|
||||||
from(rgba(0, 0, 0, 0.5)),
|
|
||||||
to(rgba(0, 0, 0, 0)));
|
|
||||||
`,
|
|
||||||
});
|
|
|
@ -1,13 +0,0 @@
|
||||||
// Types
|
|
||||||
import { PopupWindow } from 'global-types';
|
|
||||||
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
(App.windows as PopupWindow[])
|
|
||||||
.filter((w) => w &&
|
|
||||||
w.close_on_unfocus &&
|
|
||||||
w.close_on_unfocus !== 'stay')
|
|
||||||
.forEach((w) => {
|
|
||||||
App.closeWindow(w.name);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,270 +0,0 @@
|
||||||
import Gtk from 'gi://Gtk?version=3.0';
|
|
||||||
import Gdk from 'gi://Gdk?version=3.0';
|
|
||||||
|
|
||||||
// Types
|
|
||||||
import { BaseProps, Widget as AgsWidget } from 'types/widgets/widget';
|
|
||||||
type EventHandler<Self> = (self: Self, event: Gdk.Event) => boolean | unknown;
|
|
||||||
|
|
||||||
// eslint-disable-next-line
|
|
||||||
export interface CursorBox<Child, Attr> extends AgsWidget<Attr> { }
|
|
||||||
|
|
||||||
export type CursorBoxProps<
|
|
||||||
Child extends Gtk.Widget,
|
|
||||||
Attr = unknown,
|
|
||||||
Self = CursorBox<Child, Attr>,
|
|
||||||
> = BaseProps<Self, Gtk.EventBox.ConstructorProperties & {
|
|
||||||
child?: Child
|
|
||||||
on_hover?: EventHandler<Self>
|
|
||||||
on_hover_lost?: EventHandler<Self>
|
|
||||||
|
|
||||||
on_scroll_up?: EventHandler<Self>
|
|
||||||
on_scroll_down?: EventHandler<Self>
|
|
||||||
|
|
||||||
on_primary_click?: EventHandler<Self>
|
|
||||||
on_middle_click?: EventHandler<Self>
|
|
||||||
on_secondary_click?: EventHandler<Self>
|
|
||||||
|
|
||||||
on_primary_click_release?: EventHandler<Self>
|
|
||||||
on_middle_click_release?: EventHandler<Self>
|
|
||||||
on_secondary_click_release?: EventHandler<Self>
|
|
||||||
}, Attr>;
|
|
||||||
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
||||||
export class CursorBox<Child extends Gtk.Widget, Attr> extends Gtk.EventBox {
|
|
||||||
static {
|
|
||||||
Widget.register(this, {
|
|
||||||
properties: {
|
|
||||||
'on-clicked': ['jsobject', 'rw'],
|
|
||||||
|
|
||||||
'on-hover': ['jsobject', 'rw'],
|
|
||||||
'on-hover-lost': ['jsobject', 'rw'],
|
|
||||||
|
|
||||||
'on-scroll-up': ['jsobject', 'rw'],
|
|
||||||
'on-scroll-down': ['jsobject', 'rw'],
|
|
||||||
|
|
||||||
'on-primary-click': ['jsobject', 'rw'],
|
|
||||||
'on-secondary-click': ['jsobject', 'rw'],
|
|
||||||
'on-middle-click': ['jsobject', 'rw'],
|
|
||||||
|
|
||||||
'on-primary-click-release': ['jsobject', 'rw'],
|
|
||||||
'on-secondary-click-release': ['jsobject', 'rw'],
|
|
||||||
'on-middle-click-release': ['jsobject', 'rw'],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(props: CursorBoxProps<Child, Attr> = {}) {
|
|
||||||
super(props as Gtk.EventBox.ConstructorProperties);
|
|
||||||
this.add_events(Gdk.EventMask.SCROLL_MASK);
|
|
||||||
this.add_events(Gdk.EventMask.SMOOTH_SCROLL_MASK);
|
|
||||||
|
|
||||||
// Gesture stuff
|
|
||||||
const gesture = Gtk.GestureMultiPress.new(this);
|
|
||||||
|
|
||||||
this.hook(gesture, (_, _n, x, y) => {
|
|
||||||
if (!x || !y) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.#canRun.setValue(!(
|
|
||||||
x > this.get_allocated_width() ||
|
|
||||||
x <= 0 ||
|
|
||||||
y > this.get_allocated_height() ||
|
|
||||||
y <= 0
|
|
||||||
));
|
|
||||||
}, 'released');
|
|
||||||
|
|
||||||
this.connect('enter-notify-event', (_, event: Gdk.Event) => {
|
|
||||||
this.set_state_flags(Gtk.StateFlags.PRELIGHT, false);
|
|
||||||
|
|
||||||
if (!this.#display) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.window.set_cursor(Gdk.Cursor.new_from_name(
|
|
||||||
this.#display,
|
|
||||||
this.#disabled.value ?
|
|
||||||
'not-allowed' :
|
|
||||||
'pointer',
|
|
||||||
));
|
|
||||||
|
|
||||||
return this.on_hover?.(this, event);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.connect('leave-notify-event', (_, event: Gdk.Event) => {
|
|
||||||
this.unset_state_flags(Gtk.StateFlags.PRELIGHT);
|
|
||||||
|
|
||||||
this.window.set_cursor(null);
|
|
||||||
|
|
||||||
return this.on_hover_lost?.(this, event);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.connect('button-press-event', (_, event: Gdk.Event) => {
|
|
||||||
this.set_state_flags(Gtk.StateFlags.ACTIVE, false);
|
|
||||||
if (this.#disabled.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.get_button()[1] === Gdk.BUTTON_PRIMARY) {
|
|
||||||
return this.on_primary_click?.(this, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (event.get_button()[1] === Gdk.BUTTON_MIDDLE) {
|
|
||||||
return this.on_middle_click?.(this, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (event.get_button()[1] === Gdk.BUTTON_SECONDARY) {
|
|
||||||
return this.on_secondary_click?.(this, event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.connect('button-release-event', (_, event: Gdk.Event) => {
|
|
||||||
this.unset_state_flags(Gtk.StateFlags.ACTIVE);
|
|
||||||
if (this.#disabled.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.get_button()[1] === Gdk.BUTTON_PRIMARY) {
|
|
||||||
// Every click, do a one shot connect to
|
|
||||||
// CanRun to wait for location of click
|
|
||||||
const id = this.#canRun.connect('changed', () => {
|
|
||||||
if (this.#canRun.value) {
|
|
||||||
this.on_primary_click_release?.(this, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.#canRun.disconnect(id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (event.get_button()[1] === Gdk.BUTTON_MIDDLE) {
|
|
||||||
return this.on_middle_click_release?.(this, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (event.get_button()[1] === Gdk.BUTTON_SECONDARY) {
|
|
||||||
return this.on_secondary_click_release?.(this, event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.connect('scroll-event', (_, event: Gdk.Event) => {
|
|
||||||
if (event.get_scroll_deltas()[2] < 0) {
|
|
||||||
return this.on_scroll_up?.(this, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (event.get_scroll_deltas()[2] > 0) {
|
|
||||||
return this.on_scroll_down?.(this, event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.hook(this.#disabled, () => {
|
|
||||||
this.toggleClassName('disabled', this.#disabled.value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#display = Gdk.Display.get_default();
|
|
||||||
|
|
||||||
// Make this variable to know if the function should
|
|
||||||
// be executed depending on where the click is released
|
|
||||||
#canRun = Variable(true);
|
|
||||||
#disabled = Variable(false);
|
|
||||||
|
|
||||||
get disabled() {
|
|
||||||
return this.#disabled.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
set disabled(value: boolean) {
|
|
||||||
this.#disabled.setValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
get child() {
|
|
||||||
return super.child as Child;
|
|
||||||
}
|
|
||||||
|
|
||||||
set child(child: Child) {
|
|
||||||
super.child = child;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
get on_hover() {
|
|
||||||
return this._get('on-hover');
|
|
||||||
}
|
|
||||||
|
|
||||||
set on_hover(callback: EventHandler<this>) {
|
|
||||||
this._set('on-hover', callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
get on_hover_lost() {
|
|
||||||
return this._get('on-hover-lost');
|
|
||||||
}
|
|
||||||
|
|
||||||
set on_hover_lost(callback: EventHandler<this>) {
|
|
||||||
this._set('on-hover-lost', callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
get on_scroll_up() {
|
|
||||||
return this._get('on-scroll-up');
|
|
||||||
}
|
|
||||||
|
|
||||||
set on_scroll_up(callback: EventHandler<this>) {
|
|
||||||
this._set('on-scroll-up', callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
get on_scroll_down() {
|
|
||||||
return this._get('on-scroll-down');
|
|
||||||
}
|
|
||||||
|
|
||||||
set on_scroll_down(callback: EventHandler<this>) {
|
|
||||||
this._set('on-scroll-down', callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
get on_primary_click() {
|
|
||||||
return this._get('on-primary-click');
|
|
||||||
}
|
|
||||||
|
|
||||||
set on_primary_click(callback: EventHandler<this>) {
|
|
||||||
this._set('on-primary-click', callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
get on_middle_click() {
|
|
||||||
return this._get('on-middle-click');
|
|
||||||
}
|
|
||||||
|
|
||||||
set on_middle_click(callback: EventHandler<this>) {
|
|
||||||
this._set('on-middle-click', callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
get on_secondary_click() {
|
|
||||||
return this._get('on-secondary-click');
|
|
||||||
}
|
|
||||||
|
|
||||||
set on_secondary_click(callback: EventHandler<this>) {
|
|
||||||
this._set('on-secondary-click', callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
get on_primary_click_release() {
|
|
||||||
return this._get('on-primary-click-release');
|
|
||||||
}
|
|
||||||
|
|
||||||
set on_primary_click_release(callback: EventHandler<this>) {
|
|
||||||
this._set('on-primary-click-release', callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
get on_middle_click_release() {
|
|
||||||
return this._get('on-middle-click-release');
|
|
||||||
}
|
|
||||||
|
|
||||||
set on_middle_click_release(callback: EventHandler<this>) {
|
|
||||||
this._set('on-middle-click-release', callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
get on_secondary_click_release() {
|
|
||||||
return this._get('on-secondary-click-release');
|
|
||||||
}
|
|
||||||
|
|
||||||
set on_secondary_click_release(callback: EventHandler<this>) {
|
|
||||||
this._set('on-secondary-click-release', callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default <Child extends Gtk.Widget, Attr>(
|
|
||||||
props?: CursorBoxProps<Child, Attr>,
|
|
||||||
) => new CursorBox(props ?? {});
|
|
|
@ -1,54 +0,0 @@
|
||||||
const { execAsync, readFileAsync, timeout } = Utils;
|
|
||||||
const { get_home_dir } = imports.gi.GLib;
|
|
||||||
|
|
||||||
import GObject from 'types/@girs/gobject-2.0/gobject-2.0';
|
|
||||||
|
|
||||||
interface Persist {
|
|
||||||
name: string
|
|
||||||
gobject: GObject.Object
|
|
||||||
prop: string
|
|
||||||
condition?: boolean | string // If string, compare following props to this
|
|
||||||
whenTrue?: boolean | string
|
|
||||||
whenFalse?: boolean | string
|
|
||||||
signal?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default ({
|
|
||||||
name,
|
|
||||||
gobject,
|
|
||||||
prop,
|
|
||||||
condition = true,
|
|
||||||
whenTrue = condition,
|
|
||||||
whenFalse = false,
|
|
||||||
signal = 'changed',
|
|
||||||
}: Persist) => {
|
|
||||||
const cacheFile = `${get_home_dir()}/.cache/ags/.${name}`;
|
|
||||||
|
|
||||||
const stateCmd = () => ['bash', '-c',
|
|
||||||
`echo ${gobject[prop] === condition} > ${cacheFile}`];
|
|
||||||
|
|
||||||
const monitorState = () => {
|
|
||||||
gobject.connect(signal, () => {
|
|
||||||
execAsync(stateCmd()).catch(print);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
readFileAsync(cacheFile)
|
|
||||||
.then((content) => {
|
|
||||||
// JSON.parse was the only way I found to reliably
|
|
||||||
// convert a string of 'true' or 'false' into a bool
|
|
||||||
gobject[prop] = JSON.parse(content) ? whenTrue : whenFalse;
|
|
||||||
|
|
||||||
timeout(1000, () => {
|
|
||||||
monitorState();
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
execAsync(stateCmd())
|
|
||||||
.then(() => {
|
|
||||||
monitorState();
|
|
||||||
})
|
|
||||||
.catch(print);
|
|
||||||
});
|
|
||||||
};
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue