fvwmorg / fvwm3

FVWM version 3 -- the successor to fvwm2
Other
488 stars 75 forks source link

Handle _NET_WM_STATE_SKIP_TASKBAR in _NET_WM_STATE client messages #1011

Closed Zirias closed 2 months ago

Zirias commented 2 months ago

There's a stub here: https://github.com/fvwmorg/fvwm3/blob/main/fvwm/ewmh_events.c#L1199

Implementing this would allow changing taskbar visibility of a mapped window.

Here's a simple tester program:

#include <xcb/xcb.h>
#include <xcb/xcb_ewmh.h>

int main(int argc, char **argv)
{
    int toggle = 0;
    int start_skipped = 0;

    for (char *flags = argv[1]; flags && *flags; ++flags)
    {
        if (*flags == 't') toggle = 1;
        else if (*flags == 's') start_skipped = 1;
    }

    xcb_connection_t *c = xcb_connect(0, 0);
    const xcb_setup_t *setup = xcb_get_setup(c);
    xcb_screen_t *s = xcb_setup_roots_iterator(setup).data;
    xcb_ewmh_connection_t ewmh;
    xcb_ewmh_init_atoms_replies(&ewmh, xcb_ewmh_init_atoms(c, &ewmh), 0);

    uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
    uint32_t values[] = { s->white_pixel, XCB_EVENT_MASK_KEY_PRESS };

    xcb_window_t w = xcb_generate_id(c);
    xcb_create_window(c, XCB_COPY_FROM_PARENT, w, s->root, 0, 0, 100, 100, 2,
            XCB_WINDOW_CLASS_INPUT_OUTPUT, s->root_visual, mask, values);

    int skipped_set = 0;
    if (start_skipped)
    {
        xcb_ewmh_set_wm_state(&ewmh, w, 1, &ewmh._NET_WM_STATE_SKIP_TASKBAR);
        skipped_set = 1;
    }

    xcb_map_window(c, w);
    xcb_flush(c);

    xcb_generic_event_t *event;
    while ((event = xcb_wait_for_event(c)))
    {
        if (event->response_type == XCB_KEY_PRESS)
        {
            if (toggle)
            {
                xcb_ewmh_request_change_wm_state(&ewmh, 0, w,
                        XCB_EWMH_WM_STATE_TOGGLE,
                        ewmh._NET_WM_STATE_SKIP_TASKBAR, 0,
                        XCB_EWMH_CLIENT_SOURCE_TYPE_NORMAL);
            }
            else if (skipped_set)
            {
                xcb_ewmh_request_change_wm_state(&ewmh, 0, w,
                        XCB_EWMH_WM_STATE_REMOVE,
                        ewmh._NET_WM_STATE_SKIP_TASKBAR, 0,
                        XCB_EWMH_CLIENT_SOURCE_TYPE_NORMAL);
                skipped_set = 0;
            }
            else
            {
                xcb_ewmh_request_change_wm_state(&ewmh, 0, w,
                        XCB_EWMH_WM_STATE_ADD,
                        ewmh._NET_WM_STATE_SKIP_TASKBAR, 0,
                        XCB_EWMH_CLIENT_SOURCE_TYPE_NORMAL);
                skipped_set = 1;
            }
            xcb_flush(c);
        }
        free(event);
    }

    xcb_ewmh_connection_wipe(&ewmh);
    xcb_disconnect(c);
    return 0;
}

Link with -lxcb -lxcb-ewmh, run with tester [st], s means to start with taskbar skipping set, t means to use "toggle" messages (as opposed to "add" and "remove"), every key press will try to toggle the taskbar visibility.

I might try to do this myself, but I guess I have to understand that code first :)