diff --git a/src/backend/x11/internal.h b/src/backend/x11/internal.h index 9525258..db04315 100644 --- a/src/backend/x11/internal.h +++ b/src/backend/x11/internal.h @@ -9,6 +9,7 @@ #include "common/window.h" #include "interface/event.h" +#include "interface/tray.h" #define EWMH_ATOMS(X) \ X(_NET_WM_NAME) \ @@ -86,6 +87,18 @@ typedef enum cursor_t { ZDWM_CURSOR_COUNT, } cursor_t; +typedef struct tray_host_t { + bool enabled; + xcb_window_t host_window; + xcb_window_t container; + int32_t icon_size; + size_t icon_count; + tray_icons_change_cb_t icon_change_cb; + void *cb_user_data; +} tray_host_t; + +extern const tray_api_t tray_api; + typedef struct backend_t { xcb_key_symbols_t *key_symbols; xcb_connection_t *conn; @@ -109,6 +122,8 @@ typedef struct backend_t { window_list_t unmap; window_list_t map; window_list_t kill; + + tray_host_t tray; } backend_t; bool populate_window_event( diff --git a/src/backend/x11/tray.c b/src/backend/x11/tray.c new file mode 100644 index 0000000..c1633e0 --- /dev/null +++ b/src/backend/x11/tray.c @@ -0,0 +1,59 @@ +#include "interface/tray.h" + +#include +#include +#include + +#include "interface/types.h" +#include "internal.h" + +static window_id_t tray_host_window(void *handle) { + backend_t *backend = handle; + if (backend == nullptr || !backend->tray.enabled) { + return ZDWM_WINDOW_ID_INVALID; + } + + return backend->tray.host_window; +} + +static size_t tray_icon_count(void *handle) { + backend_t *backend = handle; + if (backend == nullptr || !backend->tray.enabled) return 0; + + return backend->tray.icon_count; +} + +static int32_t tray_icon_size(void *handle) { + backend_t *backend = handle; + if (backend == nullptr || !backend->tray.enabled) return 0; + + return backend->tray.icon_size; +} + +static void tray_place(void *handle, int32_t x) { + backend_t *backend = handle; + if (backend == nullptr || !backend->tray.enabled) return; + + auto conn = backend->conn; + auto tray = &backend->tray; + uint16_t value_mask = XCB_CONFIG_WINDOW_X; + xcb_configure_window_value_list_t value_list = {.x = x}; + xcb_configure_window_aux(conn, tray->container, value_mask, &value_list); +} + +static void +tray_set_listeners(void *handle, tray_icons_change_cb_t cb, void *user_data) { + backend_t *backend = handle; + if (backend == nullptr) return; + + backend->tray.icon_change_cb = cb; + backend->tray.cb_user_data = user_data; +} + +const tray_api_t tray_api = { + .host_window = tray_host_window, + .icon_count = tray_icon_count, + .icon_size = tray_icon_size, + .place = tray_place, + .set_listener = tray_set_listeners, +};