feat(ags): add screen corners

This commit is contained in:
matt1432 2023-10-16 13:55:31 -04:00
parent 7a3fb64fcc
commit 968ac9bfbf
8 changed files with 183 additions and 69 deletions

View file

@ -8,6 +8,7 @@ import { Calendar } from './js/date.js';
import { QuickSettings } from './js/quick-settings/main.js';
import Overview from './js/overview/main.js';
import AppLauncher from './js/applauncher/main.js';
import * as Corners from './js/screen-corners.js';
import { Closer, closeAll } from './js/misc/closer.js';
globalThis.closeAll = () => closeAll();
@ -43,5 +44,7 @@ export default {
QuickSettings,
Overview,
AppLauncher,
Corners.Bottomleft(),
Corners.Bottomright(),
],
};

View file

@ -1,81 +1,95 @@
import { Widget, Hyprland, Utils, Variable } from '../../imports.js';
const { Box, EventBox } = Widget;
const { Box, EventBox, Overlay } = Widget;
const Revealed = Variable(true);
const Hovering = Variable(false);
import { Gesture } from './gesture.js';
import { RoundedCorner } from '../screen-corners.js';
export const Revealer = params => Box({
style: 'min-height: 1px',
vertical: true,
children: [
Widget.Revealer({
transition: 'slide_down',
setup: self => self.revealChild = true,
properties: [
['timeouts', []],
],
connections: [[Hyprland, self => {
Utils.execAsync('hyprctl activewindow -j')
.then(result => {
let client = JSON.parse(result);
if (client.fullscreen !== Revealed.value) {
Revealed.value = client.fullscreen;
if (Revealed.value) {
setTimeout(() => {
if (Revealed.value)
self.revealChild = false
}, 2000);
}
else {
self.revealChild = true;
}
}
}).catch(print);
}]],
child: Gesture({
onHover: () => Hovering.value = true,
onHoverLost: self => {
Hovering.value = false;
if (Revealed.value) {
setTimeout(() => {
if (!Hovering.value) {
self.get_parent().get_parent().children[1].revealChild = true;
self.get_parent().revealChild = false;
}
}, 2000);
}
},
...params,
}),
export const Revealer = params => Overlay({
overlays: [
RoundedCorner('topleft', {
className: 'corner',
}),
Widget.Revealer({
connections: [[Revealed, self => {
if (Revealed.value) {
setTimeout(() => {
if (Revealed.value)
self.revealChild = true;
}, 2000);
}
else {
self.revealChild = false;
}
}]],
child: EventBox({
onHover: self => {
Hovering.value = true;
self.get_parent().get_parent().children[0].revealChild = true;
self.get_parent().revealChild = false;
},
child: Box({
style: 'min-height: 50px;',
}),
}),
RoundedCorner('topright', {
className: 'corner',
}),
],
child: Box({
style: 'min-height: 1px',
hexpand: true,
vertical: true,
children: [
Widget.Revealer({
transition: 'slide_down',
setup: self => self.revealChild = true,
properties: [
['timeouts', []],
],
connections: [[Hyprland, self => {
Utils.execAsync('hyprctl activewindow -j')
.then(result => {
let client = JSON.parse(result);
if (client.fullscreen !== Revealed.value) {
Revealed.value = client.fullscreen;
if (Revealed.value) {
setTimeout(() => {
if (Revealed.value)
self.revealChild = false
}, 2000);
}
else {
self.revealChild = true;
}
}
}).catch(print);
}]],
child: Gesture({
onHover: () => Hovering.value = true,
onHoverLost: self => {
Hovering.value = false;
if (Revealed.value) {
setTimeout(() => {
if (!Hovering.value) {
self.get_parent().get_parent().children[1].revealChild = true;
self.get_parent().revealChild = false;
}
}, 2000);
}
},
...params,
}),
}),
Widget.Revealer({
connections: [[Revealed, self => {
if (Revealed.value) {
setTimeout(() => {
if (Revealed.value)
self.revealChild = true;
}, 2000);
}
else {
self.revealChild = false;
}
}]],
child: EventBox({
onHover: self => {
Hovering.value = true;
self.get_parent().get_parent().children[0].revealChild = true;
self.get_parent().revealChild = false;
},
child: Box({
style: 'min-height: 50px;',
}),
}),
}),
],
}),
});

View file

@ -25,7 +25,6 @@ export const Bar = Window({
child: Revealer({
child: CenterBox({
className: 'transparent',
halign: 'fill',
style: 'margin: 5px',
vertical: false,

View file

@ -5,6 +5,10 @@ const ALWAYS_OPEN = [
'closer',
'bar',
'notifications',
'cornertl',
'cornertr',
'cornerbl',
'cornerbr'
];

View file

@ -0,0 +1,83 @@
import { Widget } from '../imports.js';
const { Gtk } = imports.gi;
const Lang = imports.lang;
export const RoundedCorner = (place, props) => Widget({
...props,
type: Gtk.DrawingArea,
halign: place.includes('left') ? 'start' : 'end',
valign: place.includes('top') ? 'start' : 'end',
setup: widget => {
const r = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
widget.set_size_request(r, r);
widget.connect('draw', Lang.bind(widget, (widget, cr) => {
const c = widget.get_style_context().get_property('background-color', Gtk.StateFlags.NORMAL);
const r = widget.get_style_context().get_property('border-radius', Gtk.StateFlags.NORMAL);
const borderColor = widget.get_style_context().get_property('color', Gtk.StateFlags.NORMAL);
const borderWidth = widget.get_style_context().get_border(Gtk.StateFlags.NORMAL).left; // ur going to write border-width: something anyway
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();
}));
},
});
export const Topleft = () => Widget.Window({
name: 'cornertl',
layer: 'overlay',
anchor: ['top', 'left'],
exclusive: false,
visible: true,
child: RoundedCorner('topleft', { className: 'corner', }),
});
export const Topright = () => Widget.Window({
name: 'cornertr',
layer: 'overlay',
anchor: ['top', 'right'],
exclusive: false,
visible: true,
child: RoundedCorner('topright', { className: 'corner', }),
});
export const Bottomleft = () => Widget.Window({
name: 'cornerbl',
layer: 'overlay',
anchor: ['bottom', 'left'],
exclusive: false,
visible: true,
child: RoundedCorner('bottomleft', { className: 'corner', }),
});
export const Bottomright = () => Widget.Window({
name: 'cornerbr',
layer: 'overlay',
anchor: ['bottom', 'right'],
exclusive: false,
visible: true,
child: RoundedCorner('bottomright', { className: 'corner', }),
});

View file

@ -20,3 +20,4 @@ undershoot {
@import "./widgets/player.scss";
@import "./widgets/overview.scss";
@import "./widgets/applauncher.scss";
@import "./widgets/corners.scss";

View file

@ -0,0 +1,5 @@
.corner {
background-color: black;
border-radius: 21px; //Hard code because Hyprland rounding is in px
border-width: 0.068rem;
}

View file

@ -764,3 +764,8 @@ calendar:indeterminate {
.applauncher .app image {
transition: 200ms;
margin-right: 9px; }
.corner {
background-color: black;
border-radius: 21px;
border-width: 0.068rem; }