parent
1fc5a48bf9
commit
f522c984c4
64 changed files with 182 additions and 50 deletions
nixosModules/ags-v2/config/widgets/screenshot
163
nixosModules/ags-v2/config/widgets/screenshot/main.tsx
Normal file
163
nixosModules/ags-v2/config/widgets/screenshot/main.tsx
Normal file
|
@ -0,0 +1,163 @@
|
|||
import { bind, execAsync, Variable } from 'astal';
|
||||
import { App, Gtk, Widget } from 'astal/gtk3';
|
||||
|
||||
import AstalApps from 'gi://AstalApps';
|
||||
const Applications = AstalApps.Apps.new();
|
||||
|
||||
import AstalHyprland from 'gi://AstalHyprland';
|
||||
const Hyprland = AstalHyprland.get_default();
|
||||
|
||||
import PopupWindow from '../misc/popup-window';
|
||||
import Separator from '../misc/separator';
|
||||
|
||||
import { hyprMessage } from '../../lib';
|
||||
|
||||
|
||||
const ICON_SEP = 6;
|
||||
const takeScreenshot = (selector: string, delay = 1000): void => {
|
||||
App.get_window('win-screenshot')?.set_visible(false);
|
||||
|
||||
setTimeout(() => {
|
||||
execAsync([
|
||||
'bash',
|
||||
'-c',
|
||||
`grim ${selector} - | satty -f - || true`,
|
||||
]).catch(console.error);
|
||||
}, delay);
|
||||
};
|
||||
|
||||
export default () => {
|
||||
const windowList = <box vertical /> as Widget.Box;
|
||||
|
||||
const updateWindows = async() => {
|
||||
if (!App.get_window('win-screenshot')?.visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
windowList.children = (JSON.parse(await hyprMessage('j/clients')) as AstalHyprland.Client[])
|
||||
.filter((client) => client.workspace.id === Hyprland.get_focused_workspace().get_id())
|
||||
.map((client) => (
|
||||
<button
|
||||
className="item-btn"
|
||||
cursor="pointer"
|
||||
|
||||
onButtonReleaseEvent={() => {
|
||||
takeScreenshot(`-w ${client.address}`);
|
||||
}}
|
||||
>
|
||||
<box halign={Gtk.Align.CENTER}>
|
||||
<icon icon={Applications.fuzzy_query(client.class)[0].iconName} />
|
||||
|
||||
<Separator size={ICON_SEP} />
|
||||
|
||||
<label
|
||||
label={client.title}
|
||||
truncate
|
||||
max_width_chars={50}
|
||||
/>
|
||||
</box>
|
||||
</button>
|
||||
));
|
||||
};
|
||||
|
||||
Hyprland.connect('notify::clients', updateWindows);
|
||||
Hyprland.connect('notify::focused-workspace', updateWindows);
|
||||
|
||||
const Shown = Variable<string>('monitors');
|
||||
|
||||
const stack = (
|
||||
<stack
|
||||
shown={bind(Shown)}
|
||||
transitionType={Gtk.StackTransitionType.SLIDE_LEFT_RIGHT}
|
||||
>
|
||||
<scrollable name="monitors">
|
||||
<box vertical>
|
||||
{bind(Hyprland, 'monitors').as((monitors) => monitors.map((monitor) => (
|
||||
<button
|
||||
className="item-btn"
|
||||
cursor="pointer"
|
||||
|
||||
onButtonReleaseEvent={() => {
|
||||
takeScreenshot(`-o ${monitor.name}`);
|
||||
}}
|
||||
>
|
||||
<label
|
||||
label={`${monitor.name}: ${monitor.description}`}
|
||||
truncate
|
||||
maxWidthChars={50}
|
||||
/>
|
||||
</button>
|
||||
)))}
|
||||
</box>
|
||||
</scrollable>
|
||||
|
||||
<scrollable name="windows">
|
||||
{windowList}
|
||||
</scrollable>
|
||||
</stack>
|
||||
) as Widget.Stack;
|
||||
|
||||
const StackButton = ({ label = '', iconName = '' }) => (
|
||||
<button
|
||||
cursor="pointer"
|
||||
className={bind(Shown).as((shown) =>
|
||||
`header-btn${shown === label ? ' active' : ''}`)}
|
||||
|
||||
onButtonReleaseEvent={() => {
|
||||
Shown.set(label);
|
||||
}}
|
||||
>
|
||||
<box halign={Gtk.Align.CENTER}>
|
||||
<icon icon={iconName} />
|
||||
|
||||
<Separator size={ICON_SEP} />
|
||||
|
||||
{label}
|
||||
</box>
|
||||
</button>
|
||||
) as Widget.Button;
|
||||
|
||||
const regionButton = (
|
||||
<button
|
||||
cursor="pointer"
|
||||
className="header-btn"
|
||||
|
||||
onButtonReleaseEvent={() => {
|
||||
takeScreenshot('-g "$(slurp)"', 0);
|
||||
}}
|
||||
>
|
||||
<box halign={Gtk.Align.CENTER}>
|
||||
<icon icon="tool-pencil-symbolic" />
|
||||
|
||||
<Separator size={ICON_SEP} />
|
||||
|
||||
region
|
||||
</box>
|
||||
</button>
|
||||
) as Widget.Button;
|
||||
|
||||
return (
|
||||
<PopupWindow
|
||||
name="screenshot"
|
||||
on_open={() => {
|
||||
updateWindows();
|
||||
}}
|
||||
>
|
||||
<box
|
||||
className="screenshot widget"
|
||||
vertical
|
||||
>
|
||||
<box
|
||||
className="header"
|
||||
homogeneous
|
||||
>
|
||||
<StackButton label="monitors" iconName="display-symbolic" />
|
||||
<StackButton label="windows" iconName="window-symbolic" />
|
||||
{regionButton}
|
||||
</box>
|
||||
|
||||
{stack}
|
||||
</box>
|
||||
</PopupWindow>
|
||||
);
|
||||
};
|
25
nixosModules/ags-v2/config/widgets/screenshot/style.scss
Normal file
25
nixosModules/ags-v2/config/widgets/screenshot/style.scss
Normal file
|
@ -0,0 +1,25 @@
|
|||
.screenshot {
|
||||
font-size: 30px;
|
||||
|
||||
.header {
|
||||
.header-btn {
|
||||
margin: 5px;
|
||||
transition: background 400ms;
|
||||
|
||||
&.active {
|
||||
background: $window_bg_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scrollable {
|
||||
margin: 5px;
|
||||
min-height: 400px;
|
||||
|
||||
box {
|
||||
.item-btn {
|
||||
margin: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue