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
|
||||
|
||||
## Ags
|
||||
## AGS
|
||||
|
||||
You might find it weird that most of my config is written in TypeScript.
|
||||
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
|
||||
[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.
|
||||
|
||||
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);
|
||||
login.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 = {
|
||||
ags = mkDep {
|
||||
owner = "Aylur";
|
||||
repo = "ags";
|
||||
};
|
||||
|
||||
agsV2 = mkDep {
|
||||
owner = "Aylur";
|
||||
repo = "ags";
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
}) {};
|
||||
in "${pkg}/lib/node_modules/${pkg.pname}/node_modules";
|
||||
|
||||
buildNodeTypes = {
|
||||
buildGirTypes = {
|
||||
configPath,
|
||||
packages,
|
||||
pname,
|
||||
|
|
|
@ -6,13 +6,7 @@
|
|||
osConfig,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
options.programs.ags-v2.lockPkg = lib.mkOption {
|
||||
type = with lib.types; nullOr package;
|
||||
default = null;
|
||||
};
|
||||
|
||||
config = let
|
||||
}: let
|
||||
# Inputs
|
||||
inherit (self.inputs) agsV2 gtk-session-lock;
|
||||
|
||||
|
@ -31,8 +25,24 @@
|
|||
|
||||
# Final ags package
|
||||
agsFull = agsV2Packages.ags.override {extraPackages = astalLibs;};
|
||||
in {
|
||||
programs.ags-v2.lockPkg = pkgs.writeShellApplication {
|
||||
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 = {
|
||||
# Make these accessible outside these files
|
||||
programs.ags-v2 = {
|
||||
package = agsFull;
|
||||
|
||||
lockPkg = pkgs.writeShellApplication {
|
||||
name = "lock";
|
||||
runtimeInputs = [agsFull];
|
||||
text = ''
|
||||
|
@ -45,6 +55,7 @@
|
|||
fi
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
home = {
|
||||
packages =
|
||||
|
@ -89,10 +100,10 @@
|
|||
inherit
|
||||
(import "${self}/lib" {inherit pkgs self;})
|
||||
buildNodeModules
|
||||
buildNodeTypes
|
||||
buildGirTypes
|
||||
;
|
||||
in (
|
||||
(buildNodeTypes {
|
||||
(buildGirTypes {
|
||||
pname = "agsV2";
|
||||
configPath = "${agsConfigDir}/@girs";
|
||||
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