feat(ags): use hyprland animations for popup windows
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
4e7904775b
commit
22722c27c4
19 changed files with 103 additions and 314 deletions
|
@ -23,7 +23,6 @@ animations {
|
|||
enabled = yes
|
||||
|
||||
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
|
||||
bezier = easeInOutBack, 0.68, -0.6, 0.32, 1.6
|
||||
|
||||
bezier = easeInBack, 0.36, 0, 0.66, -0.56
|
||||
bezier = easeOutBack, 0.34, 1.56, 0.64, 1
|
||||
|
|
6
modules/ags/config/global-types.d.ts
vendored
6
modules/ags/config/global-types.d.ts
vendored
|
@ -120,12 +120,12 @@ Var<Widget>,
|
|||
'is_listening' | 'is_polling' | 'value',
|
||||
Widget[]
|
||||
>;
|
||||
export type HyprTransition = 'slide' | 'slide top' | 'slide bottom' | 'slide left' |
|
||||
'slide right' | 'popin' | 'fade';
|
||||
export type CloseType = 'none' | 'stay' | 'released' | 'clicked';
|
||||
export type PopupWindowProps<Child extends Widget, Attr = unknown> =
|
||||
WindowProps<Child> & {
|
||||
transition?: RevealerProps<Widget>['transition']
|
||||
transition_duration?: number
|
||||
bezier?: string
|
||||
transition?: HyprTransition;
|
||||
on_open?(self: PopupWindow<Child, Attr>): void
|
||||
on_close?(self: PopupWindow<Child, Attr>): void
|
||||
blur?: boolean
|
||||
|
|
|
@ -54,7 +54,7 @@ export default (app: Application) => {
|
|||
attribute: { app },
|
||||
|
||||
on_primary_click_release: () => {
|
||||
App.closeWindow('applauncher');
|
||||
App.closeWindow('win-applauncher');
|
||||
app.launch();
|
||||
},
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ const Applauncher = (window_name = 'applauncher') => {
|
|||
const appList = Applications.query(text || '');
|
||||
|
||||
if (appList[0]) {
|
||||
App.closeWindow(window_name);
|
||||
App.closeWindow(`win-${window_name}`);
|
||||
appList[0].launch();
|
||||
}
|
||||
},
|
||||
|
@ -112,7 +112,7 @@ const Applauncher = (window_name = 'applauncher') => {
|
|||
|
||||
setup: (self) => {
|
||||
self.hook(App, (_, name, visible) => {
|
||||
if (name !== window_name) {
|
||||
if (name !== `win-${window_name}`) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -150,6 +150,7 @@ const Applauncher = (window_name = 'applauncher') => {
|
|||
|
||||
export default () => PopupWindow({
|
||||
name: 'applauncher',
|
||||
transition: 'slide top',
|
||||
keymode: 'on-demand',
|
||||
content: Applauncher(),
|
||||
});
|
||||
|
|
|
@ -16,7 +16,6 @@ export default () => BarRevealer({
|
|||
monitor: 1,
|
||||
exclusivity: 'exclusive',
|
||||
anchor: ['bottom', 'left', 'right'],
|
||||
transition: 'slide_up',
|
||||
bar: Box({
|
||||
vertical: true,
|
||||
children: [
|
||||
|
|
|
@ -38,7 +38,7 @@ Hyprland.connect('event', (hyprObj) => {
|
|||
}
|
||||
});
|
||||
|
||||
export default ({ bar, transition, monitor = 0, ...rest }) => {
|
||||
export default ({ anchor, bar, monitor = 0, ...rest }) => {
|
||||
const BarVisible = Variable(true);
|
||||
|
||||
FullscreenState.connect('changed', (v) => {
|
||||
|
@ -83,9 +83,25 @@ export default ({ bar, transition, monitor = 0, ...rest }) => {
|
|||
visible: BarVisible.bind().as((v) => !v),
|
||||
});
|
||||
|
||||
const rev = Revealer({
|
||||
transition,
|
||||
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,
|
||||
});
|
||||
|
||||
|
@ -94,6 +110,7 @@ export default ({ bar, transition, monitor = 0, ...rest }) => {
|
|||
layer: 'overlay',
|
||||
monitor,
|
||||
margins: [-1, -1, -1, -1],
|
||||
anchor,
|
||||
...rest,
|
||||
|
||||
attribute: {
|
||||
|
@ -105,13 +122,11 @@ export default ({ bar, transition, monitor = 0, ...rest }) => {
|
|||
css: 'min-height: 1px; padding: 1px;',
|
||||
hexpand: true,
|
||||
hpack: 'fill',
|
||||
vertical: transition === 'slide_up' ||
|
||||
transition === 'slide_down',
|
||||
vertical,
|
||||
|
||||
children: transition === 'slide_up' ||
|
||||
transition === 'slide_left' ?
|
||||
[buffer, rev] :
|
||||
[rev, buffer],
|
||||
children: isBottomOrLeft ?
|
||||
[buffer, barWrap] :
|
||||
[barWrap, buffer],
|
||||
}),
|
||||
}).on('enter-notify-event', () => {
|
||||
if (!BarVisible.value) {
|
||||
|
|
|
@ -5,11 +5,11 @@ import Clock from './clock';
|
|||
export default () => CursorBox({
|
||||
class_name: 'toggle-off',
|
||||
|
||||
on_primary_click_release: () => App.toggleWindow('calendar'),
|
||||
on_primary_click_release: () => App.toggleWindow('win-calendar'),
|
||||
|
||||
setup: (self) => {
|
||||
self.hook(App, (_, windowName, visible) => {
|
||||
if (windowName === 'calendar') {
|
||||
if (windowName === 'win-calendar') {
|
||||
self.toggleClassName('toggle-on', visible);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -14,18 +14,18 @@ export default () => CursorBox({
|
|||
class_name: 'toggle-off',
|
||||
|
||||
on_primary_click_release: (self) => {
|
||||
(App.getWindow('notification-center') as PopupWindow)
|
||||
(App.getWindow('win-notification-center') as PopupWindow)
|
||||
.set_x_pos(
|
||||
self.get_allocation(),
|
||||
'right',
|
||||
);
|
||||
|
||||
App.toggleWindow('notification-center');
|
||||
App.toggleWindow('win-notification-center');
|
||||
},
|
||||
|
||||
setup: (self) => {
|
||||
self.hook(App, (_, windowName, visible) => {
|
||||
if (windowName === 'notification-center') {
|
||||
if (windowName === 'win-notification-center') {
|
||||
self.toggleClassName('toggle-on', visible);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -32,18 +32,18 @@ export default () => {
|
|||
class_name: 'toggle-off',
|
||||
|
||||
on_primary_click_release: (self) => {
|
||||
(App.getWindow('quick-settings') as PopupWindow)
|
||||
(App.getWindow('win-quick-settings') as PopupWindow)
|
||||
.set_x_pos(
|
||||
self.get_allocation(),
|
||||
'right',
|
||||
);
|
||||
|
||||
App.toggleWindow('quick-settings');
|
||||
App.toggleWindow('win-quick-settings');
|
||||
},
|
||||
|
||||
setup: (self) => {
|
||||
self.hook(App, (_, windowName, visible) => {
|
||||
if (windowName === 'quick-settings') {
|
||||
if (windowName === 'win-quick-settings') {
|
||||
self.toggleClassName('toggle-on', visible);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -21,7 +21,6 @@ const SPACING = 12;
|
|||
export default () => BarRevealer({
|
||||
anchor: ['top', 'left', 'right'],
|
||||
exclusivity: 'exclusive',
|
||||
transition: 'slide_down',
|
||||
bar: CenterBox({
|
||||
css: 'margin: 5px 5px 5px 5px',
|
||||
class_name: 'bar',
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import Gtk from 'gi://Gtk?version=3.0';
|
||||
const Hyprland = await Service.import('hyprland');
|
||||
|
||||
const { Box, Overlay, register } = Widget;
|
||||
|
||||
const { Box, register } = Widget;
|
||||
const { timeout } = Utils;
|
||||
|
||||
// Types
|
||||
|
@ -11,15 +10,10 @@ import { Variable as Var } from 'types/variable';
|
|||
|
||||
import {
|
||||
CloseType,
|
||||
BoxGeneric,
|
||||
OverlayGeneric,
|
||||
PopupChild,
|
||||
HyprTransition,
|
||||
PopupWindowProps,
|
||||
} from 'global-types';
|
||||
|
||||
// FIXME: deal with overlay children?
|
||||
// TODO: make props changes affect the widget
|
||||
|
||||
|
||||
export class PopupWindow<
|
||||
Child extends Gtk.Widget,
|
||||
|
@ -34,9 +28,8 @@ export class PopupWindow<
|
|||
}
|
||||
|
||||
#content: Var<Gtk.Widget>;
|
||||
#antiClip: Var<boolean>;
|
||||
#needsAnticlipping: boolean;
|
||||
#close_on_unfocus: CloseType;
|
||||
#transition: HyprTransition;
|
||||
|
||||
get content() {
|
||||
return this.#content.value;
|
||||
|
@ -51,14 +44,22 @@ export class PopupWindow<
|
|||
return this.#close_on_unfocus;
|
||||
}
|
||||
|
||||
set close_on_unfocus(value: 'none' | 'stay' | 'released' | 'clicked') {
|
||||
set close_on_unfocus(value: CloseType) {
|
||||
this.#close_on_unfocus = value;
|
||||
}
|
||||
|
||||
get transition() {
|
||||
return this.#transition;
|
||||
}
|
||||
|
||||
set transition(t: HyprTransition) {
|
||||
this.#transition = t;
|
||||
Hyprland.messageAsync(`keyword layerrule animation ${t}, ${this.name}`);
|
||||
}
|
||||
|
||||
constructor({
|
||||
transition = 'slide_down',
|
||||
transition = 'slide top',
|
||||
transition_duration = 800,
|
||||
bezier = 'cubic-bezier(0.68, -0.4, 0.32, 1.4)',
|
||||
on_open = () => {/**/},
|
||||
on_close = () => {/**/},
|
||||
|
||||
|
@ -73,10 +74,7 @@ export class PopupWindow<
|
|||
close_on_unfocus = 'released',
|
||||
...rest
|
||||
}: PopupWindowProps<Child, Attr>) {
|
||||
const needsAnticlipping = bezier.match(/-[0-9]/) !== null &&
|
||||
transition !== 'crossfade';
|
||||
const contentVar = Variable(Box() as Gtk.Widget);
|
||||
const antiClip = Variable(false);
|
||||
|
||||
if (content) {
|
||||
contentVar.setValue(content);
|
||||
|
@ -84,19 +82,16 @@ export class PopupWindow<
|
|||
|
||||
super({
|
||||
...rest,
|
||||
name,
|
||||
name: `win-${name}`,
|
||||
visible,
|
||||
anchor,
|
||||
layer,
|
||||
attribute,
|
||||
setup: () => {
|
||||
const id = App.connect('config-parsed', () => {
|
||||
// Set close delay dynamically
|
||||
App.closeWindowDelay[name] = transition_duration;
|
||||
|
||||
// Add way to make window open on startup
|
||||
if (visible) {
|
||||
App.openWindow(`${name}`);
|
||||
App.openWindow(`win-${name}`);
|
||||
}
|
||||
|
||||
// This connection should always run only once
|
||||
|
@ -105,266 +100,33 @@ export class PopupWindow<
|
|||
|
||||
if (blur) {
|
||||
Hyprland.messageAsync('[[BATCH]] ' +
|
||||
`keyword layerrule ignorealpha[0.97],${name}; ` +
|
||||
`keyword layerrule blur,${name}`);
|
||||
`keyword layerrule ignorealpha 0.97, win-${name}; ` +
|
||||
`keyword layerrule blur, win-${name}`);
|
||||
}
|
||||
|
||||
Hyprland.messageAsync(
|
||||
`keyword layerrule animation ${transition}, win-${name}`,
|
||||
);
|
||||
},
|
||||
child: Overlay({
|
||||
overlays: [Box({
|
||||
css: `
|
||||
min-height: 1px;
|
||||
min-width: 1px;
|
||||
padding: 1px;
|
||||
`,
|
||||
setup: (self) => {
|
||||
// Make sure child doesn't
|
||||
// get bigger than it should
|
||||
const MAX_ANCHORS = 4;
|
||||
child: contentVar.bind(),
|
||||
});
|
||||
|
||||
self.hpack = 'center';
|
||||
self.vpack = 'center';
|
||||
|
||||
if (anchor.includes('top') &&
|
||||
anchor.includes('bottom')) {
|
||||
self.vpack = 'center';
|
||||
}
|
||||
else if (anchor.includes('top')) {
|
||||
self.vpack = 'start';
|
||||
}
|
||||
else if (anchor.includes('bottom')) {
|
||||
self.vpack = 'end';
|
||||
}
|
||||
|
||||
if (anchor.includes('left') &&
|
||||
anchor.includes('right')) {
|
||||
self.hpack = 'center';
|
||||
}
|
||||
else if (anchor.includes('left')) {
|
||||
self.hpack = 'start';
|
||||
}
|
||||
else if (anchor.includes('right')) {
|
||||
self.hpack = 'end';
|
||||
}
|
||||
|
||||
if (anchor.length === MAX_ANCHORS) {
|
||||
self.hpack = 'center';
|
||||
self.vpack = 'center';
|
||||
}
|
||||
|
||||
if (needsAnticlipping) {
|
||||
const reorder_child = (position: number) => {
|
||||
// If unanchored, we have another anticlip widget
|
||||
// so we can't change the order
|
||||
if (anchor.length !== 0) {
|
||||
for (const ch of self.children) {
|
||||
if (ch !== contentVar.value) {
|
||||
self.reorder_child(ch, position);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
self.hook(antiClip, () => {
|
||||
if (transition === 'slide_down') {
|
||||
self.vertical = true;
|
||||
reorder_child(-1);
|
||||
}
|
||||
else if (transition === 'slide_up') {
|
||||
self.vertical = true;
|
||||
reorder_child(0);
|
||||
}
|
||||
else if (transition === 'slide_right') {
|
||||
self.vertical = false;
|
||||
reorder_child(-1);
|
||||
}
|
||||
else if (transition === 'slide_left') {
|
||||
self.vertical = false;
|
||||
reorder_child(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
children: contentVar.bind().transform((v) => {
|
||||
if (needsAnticlipping) {
|
||||
return [
|
||||
// Add an anticlip widget when unanchored
|
||||
// to not have a weird animation
|
||||
anchor.length === 0 && Box({
|
||||
css: `
|
||||
min-height: 100px;
|
||||
min-width: 100px;
|
||||
padding: 2px;
|
||||
`,
|
||||
visible: antiClip.bind(),
|
||||
}),
|
||||
v,
|
||||
Box({
|
||||
css: `
|
||||
min-height: 100px;
|
||||
min-width: 100px;
|
||||
padding: 2px;
|
||||
`,
|
||||
visible: antiClip.bind(),
|
||||
}),
|
||||
];
|
||||
}
|
||||
else {
|
||||
return [v];
|
||||
}
|
||||
}) as PopupChild,
|
||||
})],
|
||||
|
||||
setup: (self) => {
|
||||
self.on('get-child-position', (_, ch) => {
|
||||
const overlay = contentVar.value
|
||||
.get_parent() as OverlayGeneric;
|
||||
|
||||
if (ch === overlay) {
|
||||
const alloc = overlay.get_allocation();
|
||||
|
||||
(self.child as BoxGeneric).css = `
|
||||
min-height: ${alloc.height}px;
|
||||
min-width: ${alloc.width}px;
|
||||
`;
|
||||
}
|
||||
this.hook(App, (_, currentName, isOpen) => {
|
||||
if (currentName === `win-${name}`) {
|
||||
if (isOpen) {
|
||||
on_open(this);
|
||||
}
|
||||
else {
|
||||
timeout(Number(transition_duration), () => {
|
||||
on_close(this);
|
||||
});
|
||||
},
|
||||
|
||||
child: Box({
|
||||
css: `
|
||||
min-height: 1px;
|
||||
min-width: 1px;
|
||||
padding: 1px;
|
||||
`,
|
||||
|
||||
setup: (self) => {
|
||||
let currentTimeout: number;
|
||||
|
||||
self.hook(App, (_, currentName, isOpen) => {
|
||||
if (currentName === name) {
|
||||
const overlay = contentVar.value
|
||||
.get_parent() as OverlayGeneric;
|
||||
|
||||
const alloc = overlay.get_allocation();
|
||||
const height = antiClip ?
|
||||
alloc.height + 100 + 10 :
|
||||
alloc.height + 10;
|
||||
|
||||
if (needsAnticlipping) {
|
||||
antiClip.setValue(true);
|
||||
|
||||
const thisTimeout = timeout(
|
||||
transition_duration,
|
||||
() => {
|
||||
// Only run the timeout if there isn't a newer timeout
|
||||
if (thisTimeout ===
|
||||
currentTimeout) {
|
||||
antiClip.setValue(false);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
currentTimeout = thisTimeout;
|
||||
}
|
||||
|
||||
let css = '';
|
||||
|
||||
/* Margin: top | right | bottom | left */
|
||||
switch (transition) {
|
||||
case 'slide_down':
|
||||
css = `margin:
|
||||
-${height}px
|
||||
0
|
||||
${height}px
|
||||
0
|
||||
;`;
|
||||
break;
|
||||
|
||||
case 'slide_up':
|
||||
css = `margin:
|
||||
${height}px
|
||||
0
|
||||
-${height}px
|
||||
0
|
||||
;`;
|
||||
break;
|
||||
|
||||
case 'slide_left':
|
||||
css = `margin:
|
||||
0
|
||||
-${height}px
|
||||
0
|
||||
${height}px
|
||||
;`;
|
||||
break;
|
||||
|
||||
case 'slide_right':
|
||||
css = `margin:
|
||||
0
|
||||
${height}px
|
||||
0
|
||||
-${height}px
|
||||
;`;
|
||||
break;
|
||||
|
||||
case 'crossfade':
|
||||
css = `
|
||||
opacity: 0;
|
||||
min-height: 1px;
|
||||
min-width: 1px;
|
||||
`;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (isOpen) {
|
||||
on_open(this);
|
||||
|
||||
// To get the animation, we need to set the css
|
||||
// to hide the widget and then timeout to have
|
||||
// the animation
|
||||
overlay.css = css;
|
||||
timeout(10, () => {
|
||||
overlay.css = `
|
||||
transition: margin
|
||||
${transition_duration}ms
|
||||
${bezier},
|
||||
|
||||
opacity
|
||||
${transition_duration}ms
|
||||
${bezier};
|
||||
`;
|
||||
});
|
||||
}
|
||||
else {
|
||||
timeout(transition_duration, () => {
|
||||
on_close(this);
|
||||
});
|
||||
|
||||
overlay.css = `${css}
|
||||
transition: margin
|
||||
${transition_duration}ms ${bezier},
|
||||
|
||||
opacity
|
||||
${transition_duration}ms ${bezier};
|
||||
`;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
}),
|
||||
}),
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.#content = contentVar;
|
||||
this.#close_on_unfocus = close_on_unfocus;
|
||||
this.#needsAnticlipping = needsAnticlipping;
|
||||
this.#antiClip = antiClip;
|
||||
this.#transition = transition;
|
||||
}
|
||||
|
||||
set_x_pos(
|
||||
|
|
|
@ -9,6 +9,7 @@ import PopupWindow from '../misc/popup.ts';
|
|||
export const NotifPopups = () => Window({
|
||||
name: 'notifications',
|
||||
anchor: ['bottom', 'left'],
|
||||
layer: 'overlay',
|
||||
monitor: 1,
|
||||
|
||||
child: PopUpsWidget(),
|
||||
|
@ -18,7 +19,7 @@ export const NotifPopups = () => Window({
|
|||
export const NotifCenter = () => PopupWindow({
|
||||
name: 'notification-center',
|
||||
anchor: ['bottom', 'right'],
|
||||
transition: 'slide_up',
|
||||
transition: 'slide bottom',
|
||||
monitor: 1,
|
||||
|
||||
content: NotifCenterWidget(),
|
||||
|
|
|
@ -76,7 +76,7 @@ const ClearButton = () => CursorBox({
|
|||
|
||||
on_primary_click_release: () => {
|
||||
Notifications.clear();
|
||||
timeout(1000, () => App.closeWindow('notification-center'));
|
||||
timeout(1000, () => App.closeWindow('win-notification-center'));
|
||||
},
|
||||
|
||||
setup: (self) => {
|
||||
|
|
|
@ -8,6 +8,7 @@ import PopupWindow from '../misc/popup.ts';
|
|||
|
||||
export const NotifPopups = () => Window({
|
||||
name: 'notifications',
|
||||
layer: 'overlay',
|
||||
anchor: ['top', 'left'],
|
||||
child: PopUpsWidget(),
|
||||
});
|
||||
|
|
|
@ -41,6 +41,8 @@ const OSDs = () => {
|
|||
}),
|
||||
);
|
||||
|
||||
stack.show_all();
|
||||
|
||||
// Delay popup method so it
|
||||
// doesn't show any OSDs at launch
|
||||
timeout(1000, () => {
|
||||
|
@ -49,13 +51,13 @@ const OSDs = () => {
|
|||
stack.attribute.popup = (osd: string) => {
|
||||
++count;
|
||||
stack.shown = osd;
|
||||
App.openWindow('osd');
|
||||
App.openWindow('win-osd');
|
||||
|
||||
timeout(HIDE_DELAY, () => {
|
||||
--count;
|
||||
|
||||
if (count === 0) {
|
||||
App.closeWindow('osd');
|
||||
App.closeWindow('win-osd');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -71,8 +73,6 @@ export default () => PopupWindow({
|
|||
anchor: ['bottom'],
|
||||
exclusivity: 'ignore',
|
||||
close_on_unfocus: 'stay',
|
||||
transition: 'slide_up',
|
||||
transition_duration,
|
||||
bezier: 'ease',
|
||||
transition: 'slide bottom',
|
||||
content: OSDs(),
|
||||
});
|
||||
|
|
|
@ -44,5 +44,6 @@ const PowermenuWidget = () => CenterBox({
|
|||
|
||||
export default () => PopupWindow({
|
||||
name: 'powermenu',
|
||||
transition: 'slide bottom',
|
||||
content: PowermenuWidget(),
|
||||
});
|
||||
|
|
|
@ -327,7 +327,7 @@ const SecondRow = () => Row({
|
|||
command: () => {
|
||||
execAsync(['lock']).catch(print);
|
||||
},
|
||||
secondary_command: () => App.openWindow('powermenu'),
|
||||
secondary_command: () => App.openWindow('win-powermenu'),
|
||||
icon: 'system-lock-screen-symbolic',
|
||||
}),
|
||||
],
|
||||
|
|
|
@ -26,7 +26,7 @@ export default () => {
|
|||
name: 'openAppLauncher',
|
||||
gesture: 'UD',
|
||||
edge: 'T',
|
||||
command: () => App.openWindow('applauncher'),
|
||||
command: () => App.openWindow('win-applauncher'),
|
||||
});
|
||||
|
||||
TouchGestures.addGesture({
|
||||
|
|
|
@ -94,19 +94,30 @@ in {
|
|||
|
||||
wayland.windowManager.hyprland = {
|
||||
settings = {
|
||||
animations.animation = [
|
||||
# Ags takes care of doing the animations
|
||||
"layers, 0"
|
||||
animations = {
|
||||
bezier = [
|
||||
"easeInOutBack, 0.68, -0.6, 0.32, 1.6"
|
||||
];
|
||||
|
||||
animation = [
|
||||
"fadeLayersIn, 0"
|
||||
"fadeLayersOut, 1, 3000, default"
|
||||
"layers, 1, 8, easeInOutBack, slide left"
|
||||
];
|
||||
};
|
||||
|
||||
layerrule = [
|
||||
"noanim, ^(?!win-).*"
|
||||
];
|
||||
|
||||
exec-once = [
|
||||
"ags"
|
||||
"sleep 3; ags -r 'App.openWindow(\"applauncher\")'"
|
||||
"sleep 3; ags -r 'App.openWindow(\"win-applauncher\")'"
|
||||
];
|
||||
|
||||
bind = [
|
||||
"$mainMod SHIFT, E, exec, ags -t powermenu"
|
||||
"$mainMod , D, exec, ags -t applauncher"
|
||||
"$mainMod SHIFT, E, exec, ags -t win-powermenu"
|
||||
"$mainMod , D, exec, ags -t win-applauncher"
|
||||
];
|
||||
binde = [
|
||||
## Brightness control
|
||||
|
|
Loading…
Reference in a new issue