Aylur / ags

Scaffoling CLI for Astal+TypeScript
https://aylur.github.io/ags/
GNU General Public License v3.0
2.26k stars 117 forks source link

Overlay passthrough prop not working #168

Closed matt1432 closed 12 months ago

matt1432 commented 1 year ago

The passthrough prop of the Overlay widget doesn't do anything. I used to do this instead:

Overlay({
    setup: self => {
        self.set_overlay_pass_through(
            self.get_children()[1],
            true,
        );
    },
    overlays: [Highlighter()],
    child: Box({
    ...

Since the subclass refactor, a timeout is necessary

Overlay({
    setup: self => {
        // FIXME: see if we can get rid of this timeout
        timeout(1, () => {
            self.set_overlay_pass_through(
                self.get_children()[1],
                true,
            );
        });
    },
    overlays: [Highlighter()],
    child: Box({
    ...

Edit: doing self.pass_through = true; inside the timeout also works but setting it as a prop does not

matt1432 commented 1 year ago

Idk if this would be a good way to fix this?

Overlay({
    connections: [['get-child-position', (self, ch) => {
        self.set_overlay_pass_through(ch, true);
    }]],
    ...

Maybe implementing something similar to this in overlay.ts

Aylur commented 1 year ago

I could not reproduce it not working when passing pass-through to the constructor. The getter however, wasn't returning the correct value

Aylur commented 1 year ago

This works as expected

import App from 'resource:///com/github/Aylur/ags/app.js';
import Widget from 'resource:///com/github/Aylur/ags/widget.js';

const overlay = Widget.Overlay({
    child: Widget.Button({
        onClicked: () => print('canclick'),
        label: 'click me'
    }),
    overlays: [
        Widget.Label({
            label: 'lay',
            hexpand: true,
            vexpand: true,
        }),
    ],
    pass_through: true,
    connections: [['notify::pass-through', self => print('toggled', self.pass_through)]]
})

const toggle = Widget.Button({
    onClicked: () => overlay.pass_through = !overlay.pass_through,
    label: 'toggle'
})

const quit = Widget.Button({
    label: 'q',
    onClicked: App.Quit.bind(App),
})

const printer = Widget.Button({
    label: 'print',
    on_clicked: () => print(overlay.pass_through)
})

const win = Widget.Window({
    name: 'test',
    focusable: true,
    child: Widget.Box({
        children: [overlay, toggle, printer, quit]
    })
})

export default { windows: [win] }
matt1432 commented 1 year ago

i'm still getting the same issue with this code:

const widget = Overlay({
        pass_through: true,
        connections: [['notify::pass-through', self => print('toggled', self.pass_through)]],
        overlays: [highlight],
        child: EventBox({
            child: Box({
                className: 'workspaces',
                properties: [
                    ['workspaces'],

                    ['refresh', self => {
                        self.children.forEach(rev => rev.reveal_child = false);
                        self._workspaces.forEach(ws => {
                            ws.revealChild = true;
                        });
                    }],

                    ['updateWorkspaces', self => {
                        Hyprland.workspaces.forEach(ws => {
                            const currentWs = self.children.find(ch => ch._id == ws.id);
                            if (!currentWs && ws.id > 0)
                                self.add(Workspace({ i: ws.id }));
                        });
                        self.show_all();

                        // Make sure the order is correct
                        self._workspaces.forEach((workspace, i) => {
                            workspace.get_parent().reorder_child(workspace, i);
                        });
                    }],
                ],
                connections: [[Hyprland, self => {
                    self._workspaces = self.children.filter(ch => {
                        return Hyprland.workspaces.find(ws => ws.id == ch._id);
                    }).sort((a, b) => a._id - b._id);

                    self._updateWorkspaces(self);
                    self._refresh(self);

                    // Make sure the highlight doesn't go too far
                    timeout(10, updateHighlight);
                }]],
            }),
        }),
    });

log

toggled false
Aylur commented 1 year ago

Can you give a full example where it doesn't work, preferably in a single file, so I can test it with ags -c overlay.js?

matt1432 commented 1 year ago

Can you give a full example where it doesn't work, preferably in a single file, so I can test it with ags -c overlay.js?

there you go:

import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
import { timeout } from 'resource:///com/github/Aylur/ags/utils.js';
import { Box, EventBox, Overlay, Revealer, Window } from 'resource:///com/github/Aylur/ags/widget.js';

const Workspace = ({ i } = {}) =>
    Revealer({
        transition: 'slide_right',
        properties: [['id', i]],

        child: EventBox({
            tooltipText: `${i}`,
            onPrimaryClickRelease: () => Hyprland.sendMessage(`dispatch workspace ${i}`),
            child: Box({
                vpack: 'center',
                css: `
                  margin: 0 4.5px;
                  min-height: 50px;
                  min-width: 50px;
                  border-radius: 100%;
                  background: pink;
                `,
            }),
        }),
    });

const WorkspaceOverlay = () => {
    const updateHighlight = () => {
        const currentId = Hyprland.active.workspace.id;
        const indicators = highlight.get_parent().get_children()[0].child.children;
        const currentIndex = indicators.findIndex(w => w._id == currentId);

        if (currentIndex < 0)
            return;

        highlight.setCss(`margin-left: ${16 + currentIndex * (50 + 8)}px`);
    };
    const highlight = Box({
        vpack: 'center',
        hpack: 'start',
        css: `
          margin: 0 2.5px;
          min-height: 50px;
          min-width: 50px;
          border-radius: 100%;
          border: 2px solid #50fa7b;
          transition: margin-left 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
        `,
        connections: [[Hyprland.active.workspace, updateHighlight]],
    });

    const widget = Overlay({
        // FIXME: no worky pls help
        pass_through: true,

        // This works tho
        // setup: self => timeout(1, () => self.pass_through = true),

        overlays: [highlight],
        child: EventBox({
            child: Box({
                css: `
                  background-color: rgba(40, 42, 54, 0.8);
                  border-radius: 80px;
                  border: 2px solid #382c4a;
                  padding: 3px 12px;
                `,
                properties: [
                    ['workspaces'],

                    ['refresh', self => {
                        self.children.forEach(rev => rev.reveal_child = false);
                        self._workspaces.forEach(ws => {
                            ws.revealChild = true;
                        });
                    }],

                    ['updateWorkspaces', self => {
                        Hyprland.workspaces.forEach(ws => {
                            const currentWs = self.children.find(ch => ch._id == ws.id);
                            if (!currentWs && ws.id > 0)
                                self.add(Workspace({ i: ws.id }));
                        });
                        self.show_all();

                        // Make sure the order is correct
                        self._workspaces.forEach((workspace, i) => {
                            workspace.get_parent().reorder_child(workspace, i);
                        });
                    }],
                ],
                connections: [[Hyprland, self => {
                    self._workspaces = self.children.filter(ch => {
                        return Hyprland.workspaces.find(ws => ws.id == ch._id);
                    }).sort((a, b) => a._id - b._id);

                    self._updateWorkspaces(self);
                    self._refresh(self);

                    // Make sure the highlight doesn't go too far
                    timeout(10, updateHighlight);
                }]],
            }),
        }),
    });

    return widget;
};

export default {
    windows: [
        Window({
            name: 'overlay',
            child: WorkspaceOverlay(),
        }),
    ],
};