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