feat(bar): 添加状态栏 bar 模块的基础架构和 workspace 指示器
This commit is contained in:
@@ -31,6 +31,9 @@ add_executable(${APP_NAME}
|
||||
${SOURCE_DIR}/backend/x11/event.c
|
||||
${SOURCE_DIR}/backend/x11/window.c
|
||||
|
||||
${SOURCE_DIR}/bar/cell.c
|
||||
${SOURCE_DIR}/bar/workspaces.c
|
||||
|
||||
${SOURCE_DIR}/base/color.c
|
||||
${SOURCE_DIR}/base/log.c
|
||||
${SOURCE_DIR}/base/process.c
|
||||
|
||||
75
include/zdwm/bar.h
Normal file
75
include/zdwm/bar.h
Normal file
@@ -0,0 +1,75 @@
|
||||
#ifndef ZDWM_BAR_H
|
||||
#define ZDWM_BAR_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <zdwm/action.h>
|
||||
#include <zdwm/types.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct zdwm_bar_config_t {
|
||||
int32_t height;
|
||||
bool show_top; /* 如果为 false 则 bar 显示在屏幕底部 */
|
||||
uint8_t padding_x;
|
||||
uint16_t fps;
|
||||
const char *font_family;
|
||||
uint32_t font_size;
|
||||
uint32_t dpi;
|
||||
|
||||
const char *bg;
|
||||
const char *fg;
|
||||
const char *layout_bg;
|
||||
const char *layout_fg;
|
||||
const char *binding_mode_bg;
|
||||
const char *binding_mode_fg;
|
||||
const char *window_bg;
|
||||
const char *window_fg;
|
||||
const char *window_focused_bg;
|
||||
const char *window_focused_fg;
|
||||
} zdwm_bar_config_t;
|
||||
|
||||
typedef struct zdwm_bar_item_t zdwm_bar_item_t;
|
||||
|
||||
typedef struct zdwm_bar_cell_api_t {
|
||||
size_t (*get_cell_count)(zdwm_bar_item_t *item);
|
||||
void (*set_cell_count)(zdwm_bar_item_t *item, size_t count);
|
||||
|
||||
void (*cell_set_text)(zdwm_bar_item_t *item, size_t index, const char *text);
|
||||
void (*cell_set_bg)(zdwm_bar_item_t *item, size_t index, const char *color);
|
||||
void (*cell_set_fg)(zdwm_bar_item_t *item, size_t index, const char *color);
|
||||
void (*cell_set_icon)(zdwm_bar_item_t *item, size_t index, zdwm_icon_t icon);
|
||||
void (*cell_set_indicator)(zdwm_bar_item_t *item, size_t index, bool show);
|
||||
} zdwm_bar_cell_api_t;
|
||||
|
||||
typedef struct zdwm_bar_item_type_t {
|
||||
void *(*create_state)(zdwm_output_id_t output_id, void *config);
|
||||
void (*update)(
|
||||
zdwm_bar_item_t *item,
|
||||
const zdwm_bar_cell_api_t *cells,
|
||||
void *state
|
||||
);
|
||||
zdwm_action_t (*on_click)(
|
||||
zdwm_bar_item_t *item,
|
||||
size_t cell_index,
|
||||
int32_t x,
|
||||
void *state
|
||||
);
|
||||
void (*destroy_state)(void *state);
|
||||
uint32_t update_interval_ms;
|
||||
} zdwm_bar_item_type_t;
|
||||
|
||||
typedef enum zdwm_bar_side_type_t {
|
||||
ZDWM_BAR_SIDE_LEFT,
|
||||
ZDWM_BAR_SIDE_RIGHT,
|
||||
ZDWM_BAR_SIDE_CENTER_REST, /* 中央剩余部分,用于显示窗口列表 */
|
||||
ZDWM_BAR_SIDE_COUNT,
|
||||
} zdwm_bar_side_type_t;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZDWM_BAR_H */
|
||||
@@ -30,6 +30,19 @@ typedef struct zdwm_output_info_t {
|
||||
zdwm_rect_t geometry;
|
||||
} zdwm_output_info_t;
|
||||
|
||||
typedef enum zdwm_icon_type_t {
|
||||
ZDWM_ICON_TEXT,
|
||||
ZDWM_ICON_IMAGE,
|
||||
} zdwm_icon_type_t;
|
||||
|
||||
typedef struct zdwm_icon_t {
|
||||
zdwm_icon_type_t type;
|
||||
union {
|
||||
const char *text;
|
||||
const char *image_path;
|
||||
} as;
|
||||
} zdwm_icon_t;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
1
src/bar/.clang-format
Symbolic link
1
src/bar/.clang-format
Symbolic link
@@ -0,0 +1 @@
|
||||
../../.clang-format
|
||||
22
src/bar/bar.h
Normal file
22
src/bar/bar.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <zdwm/bar.h>
|
||||
#include <zdwm/types.h>
|
||||
|
||||
#include "bar/types.h"
|
||||
|
||||
typedef struct bar_output_t {
|
||||
zdwm_window_id_t window_id;
|
||||
zdwm_output_id_t output_id;
|
||||
bar_side_t sides[ZDWM_BAR_SIDE_COUNT];
|
||||
} bar_output_t;
|
||||
|
||||
typedef struct bar_t {
|
||||
bar_output_t *bars;
|
||||
size_t count;
|
||||
|
||||
bool visible;
|
||||
|
||||
zdwm_bar_config_t config;
|
||||
} bar_t;
|
||||
142
src/bar/cell.c
Normal file
142
src/bar/cell.c
Normal file
@@ -0,0 +1,142 @@
|
||||
#include "bar/cell.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <strings.h>
|
||||
#include <zdwm/types.h>
|
||||
|
||||
#include "bar/types.h"
|
||||
#include "base/array.h"
|
||||
#include "base/color.h"
|
||||
#include "base/memory.h"
|
||||
|
||||
typedef struct color_cache_item_t {
|
||||
const char *text;
|
||||
color_t color;
|
||||
} color_cache_item_t;
|
||||
|
||||
typedef struct color_cache_t {
|
||||
color_cache_item_t *items;
|
||||
size_t count;
|
||||
size_t capacity;
|
||||
} color_cache_t;
|
||||
|
||||
static color_cache_t cache = {};
|
||||
|
||||
static color_t *find_or_insert_color(const char *text) {
|
||||
assert(text);
|
||||
for (size_t i = 0; i < cache.count; ++i) {
|
||||
auto item = &cache.items[i];
|
||||
if (text == item->text || strcasecmp(text, item->text) == 0) {
|
||||
return &item->color;
|
||||
}
|
||||
}
|
||||
|
||||
auto slot = array_push(cache.items, cache.count, cache.capacity);
|
||||
slot->text = p_strdup(text);
|
||||
color_parse(text, &slot->color);
|
||||
return &slot->color;
|
||||
}
|
||||
|
||||
void bar_cell_reset_color_cache(void) {
|
||||
for (size_t i = 0; i < cache.count; ++i) {
|
||||
auto item = &cache.items[i];
|
||||
p_delete(&item->text);
|
||||
}
|
||||
p_clear(cache.items, cache.count);
|
||||
cache.count = 0;
|
||||
}
|
||||
|
||||
void bar_cell_clean_color_cache(void) {
|
||||
bar_cell_reset_color_cache();
|
||||
p_delete(&cache.items);
|
||||
cache.capacity = 0;
|
||||
}
|
||||
|
||||
size_t bar_cell_get_count(zdwm_bar_item_t *item) { return item->count; }
|
||||
|
||||
void bar_cell_set_count(zdwm_bar_item_t *item, size_t count) {
|
||||
if (item->count == count) return;
|
||||
|
||||
item->count = count;
|
||||
p_realloc(&item->cells, count);
|
||||
p_clear(item->cells, count);
|
||||
item->dirty = true;
|
||||
}
|
||||
|
||||
void bar_cell_set_text(zdwm_bar_item_t *item, size_t index, const char *text) {
|
||||
if (index >= item->count) return;
|
||||
|
||||
auto cell = &item->cells[index];
|
||||
if (cell->text == text || strcmp(cell->text, text) == 0) return;
|
||||
|
||||
cell->text = text;
|
||||
|
||||
cell->dirty = true;
|
||||
item->dirty = true;
|
||||
}
|
||||
|
||||
void bar_cell_set_bg(zdwm_bar_item_t *item, size_t index, const char *color) {
|
||||
if (index >= item->count) return;
|
||||
|
||||
auto cell = &item->cells[index];
|
||||
auto cached_color = find_or_insert_color(color);
|
||||
if (cell->bg == cached_color) return;
|
||||
|
||||
cell->bg = cached_color;
|
||||
|
||||
cell->dirty = true;
|
||||
item->dirty = true;
|
||||
}
|
||||
|
||||
void bar_cell_set_fg(zdwm_bar_item_t *item, size_t index, const char *color) {
|
||||
if (index >= item->count) return;
|
||||
|
||||
auto cell = &item->cells[index];
|
||||
auto cached_color = find_or_insert_color(color);
|
||||
if (cell->fg == cached_color) return;
|
||||
|
||||
cell->fg = cached_color;
|
||||
|
||||
cell->dirty = true;
|
||||
item->dirty = true;
|
||||
}
|
||||
|
||||
void bar_cell_set_icon(zdwm_bar_item_t *item, size_t index, zdwm_icon_t icon) {
|
||||
if (index >= item->count) return;
|
||||
|
||||
auto cell = &item->cells[index];
|
||||
auto icon_ptr = &cell->icon;
|
||||
|
||||
if (icon_ptr->type == icon.type) {
|
||||
switch (icon.type) {
|
||||
case ZDWM_ICON_TEXT:
|
||||
if (icon_ptr->as.text == icon.as.text ||
|
||||
strcmp(icon_ptr->as.text, icon.as.text) == 0) {
|
||||
return;
|
||||
}
|
||||
case ZDWM_ICON_IMAGE:
|
||||
if (icon_ptr->as.image_path == icon.as.image_path ||
|
||||
strcmp(icon_ptr->as.image_path, icon.as.image_path) == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*icon_ptr = icon;
|
||||
|
||||
cell->dirty = true;
|
||||
item->dirty = true;
|
||||
}
|
||||
|
||||
void bar_cell_set_indicator(zdwm_bar_item_t *item, size_t index, bool show) {
|
||||
if (index >= item->count) return;
|
||||
|
||||
auto cell = &item->cells[index];
|
||||
if (cell->show_indicator == show) return;
|
||||
|
||||
cell->show_indicator = show;
|
||||
|
||||
cell->dirty = true;
|
||||
item->dirty = true;
|
||||
}
|
||||
14
src/bar/cell.h
Normal file
14
src/bar/cell.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <zdwm/bar.h>
|
||||
#include <zdwm/types.h>
|
||||
|
||||
size_t bar_cell_get_count(zdwm_bar_item_t *item);
|
||||
void bar_cell_set_count(zdwm_bar_item_t *item, size_t count);
|
||||
|
||||
void bar_cell_set_text(zdwm_bar_item_t *item, size_t index, const char *text);
|
||||
void bar_cell_set_bg(zdwm_bar_item_t *item, size_t index, const char *color);
|
||||
void bar_cell_set_fg(zdwm_bar_item_t *item, size_t index, const char *color);
|
||||
void bar_cell_set_icon(zdwm_bar_item_t *item, size_t index, zdwm_icon_t icon);
|
||||
void bar_cell_set_indicator(zdwm_bar_item_t *item, size_t index, bool show);
|
||||
50
src/bar/types.h
Normal file
50
src/bar/types.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <zdwm/bar.h>
|
||||
#include <zdwm/types.h>
|
||||
|
||||
#include "base/color.h"
|
||||
|
||||
typedef struct bar_x_region_t {
|
||||
int32_t start;
|
||||
int32_t end;
|
||||
} bar_x_region_t;
|
||||
|
||||
typedef struct bar_cell_t {
|
||||
zdwm_icon_t icon;
|
||||
const char *text;
|
||||
const color_t *fg;
|
||||
const color_t *bg;
|
||||
bar_x_region_t region;
|
||||
bool show_indicator;
|
||||
bool dirty;
|
||||
} bar_cell_t;
|
||||
|
||||
struct zdwm_bar_item_t {
|
||||
bar_cell_t *cells;
|
||||
size_t count;
|
||||
bar_x_region_t region;
|
||||
void *state;
|
||||
uint8_t cell_padding;
|
||||
uint8_t indicator_width;
|
||||
bool dirty;
|
||||
};
|
||||
|
||||
typedef struct bar_side_t {
|
||||
zdwm_bar_side_type_t type;
|
||||
zdwm_bar_item_t *items;
|
||||
size_t count;
|
||||
size_t capacity;
|
||||
bar_x_region_t region;
|
||||
} bar_side_t;
|
||||
|
||||
typedef struct bars_t {
|
||||
size_t count;
|
||||
int32_t height;
|
||||
bool show_top; /* 如果为 false 则 bar 显示屏幕底部 */
|
||||
bool visible;
|
||||
|
||||
zdwm_bar_config_t config;
|
||||
} bars_t;
|
||||
224
src/bar/workspaces.c
Normal file
224
src/bar/workspaces.c
Normal file
@@ -0,0 +1,224 @@
|
||||
#include "bar/workspaces.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <zdwm/action.h>
|
||||
#include <zdwm/bar.h>
|
||||
#include <zdwm/listeners.h>
|
||||
#include <zdwm/types.h>
|
||||
|
||||
#include "base/array.h"
|
||||
#include "base/memory.h"
|
||||
|
||||
static size_t state_workspace_get_urgent_window_count(
|
||||
const bar_workspace_state_t *state,
|
||||
zdwm_workspace_id_t workspace_id
|
||||
) {
|
||||
size_t count = 0;
|
||||
|
||||
for (size_t i = 0; i < state->window_count; ++i) {
|
||||
auto window = &state->windows[i];
|
||||
if (window->workspace == workspace_id && window->urgent) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static size_t state_workspace_get_window_count(
|
||||
const bar_workspace_state_t *state,
|
||||
zdwm_workspace_id_t workspace_id
|
||||
) {
|
||||
size_t count = 0;
|
||||
|
||||
for (size_t i = 0; i < state->window_count; ++i) {
|
||||
auto window = &state->windows[i];
|
||||
if (window->workspace == workspace_id && !window->skip_taskbar) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static zdwm_window_t *state_get_window(
|
||||
const bar_workspace_state_t *state,
|
||||
zdwm_window_id_t window_id
|
||||
) {
|
||||
for (size_t i = 0; i < state->window_count; ++i) {
|
||||
auto window = &state->windows[i];
|
||||
if (window->id == window_id) return window;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void *bar_workspaces_create_state(zdwm_output_id_t output_id, void *config) {
|
||||
const bar_workspace_palette_t *palette = config;
|
||||
assert(palette);
|
||||
|
||||
auto state = p_new(bar_workspace_state_t, 1);
|
||||
state->output_id = output_id;
|
||||
state->palette = *palette;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void bar_workspaces_update(
|
||||
zdwm_bar_item_t *item,
|
||||
const zdwm_bar_cell_api_t *cell_api,
|
||||
void *state
|
||||
) {
|
||||
auto data = (bar_workspace_state_t *)state;
|
||||
if (!data->list_inited || !data->active_inited || !data->dirty) return;
|
||||
|
||||
if (data->count != cell_api->get_cell_count(item)) {
|
||||
cell_api->set_cell_count(item, data->count);
|
||||
}
|
||||
|
||||
auto palette = &data->palette;
|
||||
for (size_t i = 0; i < data->count; ++i) {
|
||||
auto workspace = &data->workspaces[i];
|
||||
auto info = &workspace->info;
|
||||
|
||||
workspace->window_count = state_workspace_get_window_count(state, info->id);
|
||||
workspace->urgent_window_count =
|
||||
state_workspace_get_urgent_window_count(state, info->id);
|
||||
|
||||
bool show_indicator = workspace->window_count;
|
||||
cell_api->cell_set_indicator(item, i, show_indicator);
|
||||
|
||||
cell_api->cell_set_text(item, i, info->name);
|
||||
if (info->id == data->workspace_id) {
|
||||
cell_api->cell_set_bg(item, i, palette->active_bg);
|
||||
cell_api->cell_set_fg(item, i, palette->active_fg);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (workspace->urgent_window_count > 0) {
|
||||
cell_api->cell_set_bg(item, i, palette->urgent_bg);
|
||||
cell_api->cell_set_fg(item, i, palette->urgent_fg);
|
||||
continue;
|
||||
}
|
||||
|
||||
cell_api->cell_set_bg(item, i, palette->bg);
|
||||
cell_api->cell_set_fg(item, i, palette->fg);
|
||||
}
|
||||
|
||||
data->dirty = false;
|
||||
}
|
||||
|
||||
zdwm_action_t bar_workspace_on_click(
|
||||
zdwm_bar_item_t *item,
|
||||
size_t cell_index,
|
||||
int32_t x,
|
||||
void *state
|
||||
) {
|
||||
auto data = (bar_workspace_state_t *)state;
|
||||
auto workspace = &data->workspaces[cell_index];
|
||||
|
||||
if (workspace->info.id == data->workspace_id) {
|
||||
return (zdwm_action_t){.type = ZDWM_ACTION_NONE};
|
||||
}
|
||||
|
||||
return (zdwm_action_t){
|
||||
.type = ZDWM_ACTION_WORKSPACE_SWITCH,
|
||||
.as.switch_workspace.workspace = workspace->info.id,
|
||||
};
|
||||
}
|
||||
|
||||
void bar_workspace_destroy_state(void *state) {
|
||||
auto data = (bar_workspace_state_t *)state;
|
||||
p_delete(&data->workspaces);
|
||||
p_clear(data, 1);
|
||||
}
|
||||
|
||||
void bar_workspace_list_filter(
|
||||
const zdwm_workspace_t *list,
|
||||
size_t count,
|
||||
void *user_data
|
||||
) {
|
||||
auto state = (bar_workspace_state_t *)user_data;
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
auto workspace = &list[i];
|
||||
if (workspace->output_id != state->output_id) continue;
|
||||
|
||||
auto item = array_push(state->workspaces, state->count, state->capacity);
|
||||
p_clear(item, 1);
|
||||
item->info = *workspace;
|
||||
}
|
||||
|
||||
state->list_inited = true;
|
||||
state->dirty = true;
|
||||
}
|
||||
|
||||
void bar_workspace_active_updated(
|
||||
zdwm_output_id_t output_id,
|
||||
zdwm_workspace_id_t workspace_id,
|
||||
void *user_data
|
||||
) {
|
||||
auto state = (bar_workspace_state_t *)user_data;
|
||||
if (state->output_id != output_id) return;
|
||||
if (state->workspace_id == workspace_id) return;
|
||||
|
||||
state->workspace_id = workspace_id;
|
||||
|
||||
state->active_inited = true;
|
||||
state->dirty = true;
|
||||
}
|
||||
|
||||
void bar_workspace_initial_windows(
|
||||
const zdwm_window_t *list,
|
||||
size_t count,
|
||||
void *user_data
|
||||
) {
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
auto window = &list[i];
|
||||
bar_workspace_window_added(window, user_data);
|
||||
}
|
||||
}
|
||||
|
||||
void bar_workspace_window_added(const zdwm_window_t *window, void *user_data) {
|
||||
auto state = (bar_workspace_state_t *)user_data;
|
||||
|
||||
auto win =
|
||||
array_push(state->windows, state->window_count, state->window_capacity);
|
||||
*win = *window;
|
||||
|
||||
state->dirty = true;
|
||||
}
|
||||
|
||||
void bar_workspace_window_updated(
|
||||
const zdwm_window_t *window,
|
||||
void *user_data
|
||||
) {
|
||||
auto state = (bar_workspace_state_t *)user_data;
|
||||
|
||||
auto old_window = state_get_window(state, window->id);
|
||||
*old_window = *window;
|
||||
state->dirty = true;
|
||||
}
|
||||
|
||||
void bar_workspace_window_removed(zdwm_window_id_t window_id, void *user_data) {
|
||||
auto state = (bar_workspace_state_t *)user_data;
|
||||
|
||||
bool found = false;
|
||||
size_t index = 0;
|
||||
|
||||
for (size_t i = 0; i < state->window_count; ++i) {
|
||||
auto window = &state->windows[i];
|
||||
if (window->id == window_id) {
|
||||
found = true;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) return;
|
||||
|
||||
if (array_erase(state->windows, state->window_count, index)) {
|
||||
state->dirty = true;
|
||||
}
|
||||
}
|
||||
73
src/bar/workspaces.h
Normal file
73
src/bar/workspaces.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <zdwm/action.h>
|
||||
#include <zdwm/bar.h>
|
||||
#include <zdwm/listeners.h>
|
||||
#include <zdwm/types.h>
|
||||
|
||||
typedef struct bar_workspace_palette_t {
|
||||
const char *bg;
|
||||
const char *fg;
|
||||
const char *active_bg;
|
||||
const char *active_fg;
|
||||
const char *urgent_bg;
|
||||
const char *urgent_fg;
|
||||
} bar_workspace_palette_t;
|
||||
|
||||
typedef struct bar_workspace_t {
|
||||
zdwm_workspace_t info;
|
||||
size_t window_count;
|
||||
size_t urgent_window_count;
|
||||
} bar_workspace_t;
|
||||
|
||||
typedef struct bar_workspace_state_t {
|
||||
zdwm_output_id_t output_id;
|
||||
zdwm_workspace_id_t workspace_id;
|
||||
bar_workspace_t *workspaces;
|
||||
size_t count;
|
||||
size_t capacity;
|
||||
|
||||
zdwm_window_t *windows;
|
||||
size_t window_count;
|
||||
size_t window_capacity;
|
||||
|
||||
bar_workspace_palette_t palette;
|
||||
|
||||
bool list_inited;
|
||||
bool active_inited;
|
||||
bool dirty;
|
||||
} bar_workspace_state_t;
|
||||
|
||||
void *bar_workspaces_create_state(zdwm_output_id_t output_id, void *config);
|
||||
void bar_workspaces_update(
|
||||
zdwm_bar_item_t *item,
|
||||
const zdwm_bar_cell_api_t *cell_api,
|
||||
void *state
|
||||
);
|
||||
zdwm_action_t bar_workspace_on_click(
|
||||
zdwm_bar_item_t *item,
|
||||
size_t cell_index,
|
||||
int32_t x,
|
||||
void *state
|
||||
);
|
||||
void bar_workspace_destroy_state(void *state);
|
||||
|
||||
void bar_workspace_list_filter(
|
||||
const zdwm_workspace_t *list,
|
||||
size_t count,
|
||||
void *user_data
|
||||
);
|
||||
void bar_workspace_active_updated(
|
||||
zdwm_output_id_t output_id,
|
||||
zdwm_workspace_id_t workspace_id,
|
||||
void *user_data
|
||||
);
|
||||
void bar_workspace_initial_windows(
|
||||
const zdwm_window_t *list,
|
||||
size_t count,
|
||||
void *user_data
|
||||
);
|
||||
void bar_workspace_window_added(const zdwm_window_t *window, void *user_data);
|
||||
void bar_workspace_window_updated(const zdwm_window_t *window, void *user_data);
|
||||
void bar_workspace_window_removed(zdwm_window_id_t window_id, void *user_data);
|
||||
Reference in New Issue
Block a user