Compare commits

...

2 Commits

12 changed files with 660 additions and 50 deletions

View File

@@ -31,6 +31,9 @@ add_executable(${APP_NAME}
${SOURCE_DIR}/backend/x11/event.c ${SOURCE_DIR}/backend/x11/event.c
${SOURCE_DIR}/backend/x11/window.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/color.c
${SOURCE_DIR}/base/log.c ${SOURCE_DIR}/base/log.c
${SOURCE_DIR}/base/process.c ${SOURCE_DIR}/base/process.c

View File

@@ -9,11 +9,13 @@ extern "C" {
#endif #endif
typedef enum zdwm_action_type_t { typedef enum zdwm_action_type_t {
ZDWM_ACTION_NONE,
ZDWM_ACTION_SPAWN, ZDWM_ACTION_SPAWN,
ZDWM_ACTION_QUIT, ZDWM_ACTION_QUIT,
ZDWM_ACTION_RAISE_OR_RUN, ZDWM_ACTION_RAISE_OR_RUN,
ZDWM_ACTION_OUTPUT_CYCLE, ZDWM_ACTION_OUTPUT_CYCLE,
ZDWM_ACTION_WORKSPACE_SWITCH,
ZDWM_ACTION_WORKSPACE_SWITCH_SAME_OUTPUT_BY_INDEX, ZDWM_ACTION_WORKSPACE_SWITCH_SAME_OUTPUT_BY_INDEX,
ZDWM_ACTION_LAYOUT_CYCLE, ZDWM_ACTION_LAYOUT_CYCLE,
ZDWM_ACTION_BINDING_MODE_CYCLE, ZDWM_ACTION_BINDING_MODE_CYCLE,
@@ -52,6 +54,10 @@ typedef struct zdwm_action_data_index_only_t {
uint32_t index; uint32_t index;
} zdwm_action_data_index_only_t; } zdwm_action_data_index_only_t;
typedef struct zdwm_action_data_switch_workspace_t {
zdwm_workspace_id_t workspace;
} zdwm_action_data_switch_workspace_t;
typedef struct zdwm_action_data_window_send_to_workspace_t { typedef struct zdwm_action_data_window_send_to_workspace_t {
uint32_t index; uint32_t index;
bool switch_workspace; bool switch_workspace;
@@ -70,6 +76,7 @@ typedef struct zdwm_action_t {
zdwm_action_data_raise_or_run_t raise_or_run; zdwm_action_data_raise_or_run_t raise_or_run;
zdwm_action_data_delta_only_t output_cycle; zdwm_action_data_delta_only_t output_cycle;
zdwm_action_data_index_only_t workspace_switch_same_output_by_index; zdwm_action_data_index_only_t workspace_switch_same_output_by_index;
zdwm_action_data_switch_workspace_t switch_workspace;
zdwm_action_data_delta_only_t layout_cycle; zdwm_action_data_delta_only_t layout_cycle;
zdwm_action_data_delta_only_t binding_mode_cycle; zdwm_action_data_delta_only_t binding_mode_cycle;
zdwm_action_data_delta_only_t window_focus_cycle; zdwm_action_data_delta_only_t window_focus_cycle;

75
include/zdwm/bar.h Normal file
View 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 */

View File

@@ -30,6 +30,19 @@ typedef struct zdwm_output_info_t {
zdwm_rect_t geometry; zdwm_rect_t geometry;
} zdwm_output_info_t; } 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) #if defined(__cplusplus)
} }
#endif #endif

1
src/bar/.clang-format Symbolic link
View File

@@ -0,0 +1 @@
../../.clang-format

22
src/bar/bar.h Normal file
View 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
View 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
View 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
View 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
View 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
View 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);

View File

@@ -60,6 +60,26 @@ get_next_window_by_class(const state_t *state, const char *class_name) {
return nullptr; return nullptr;
} }
static void add_switch_workspace_command(
command_buffer_t *command_buffer,
workspace_id_t workspace
) {
command_t switch_workspace_cmd = {
.type = ZDWM_COMMAND_SWITCH_WORKSPACE,
.as.switch_workspace.workspace = workspace,
};
command_buffer_push(command_buffer, &switch_workspace_cmd);
}
static void
add_focus_window_command(command_buffer_t *command_buffer, window_id_t window) {
command_t focus_command = {
.type = ZDWM_COMMAND_FOCUS_WINDOW,
.as.focus.window = window,
};
command_buffer_push(command_buffer, &focus_command);
}
static void raise_or_run( static void raise_or_run(
const state_t *state, const state_t *state,
const zdwm_action_data_raise_or_run_t *data, const zdwm_action_data_raise_or_run_t *data,
@@ -71,17 +91,8 @@ static void raise_or_run(
return; return;
} }
command_t switch_workspace_cmd = { add_switch_workspace_command(command_buffer, window->workspace_id);
.type = ZDWM_COMMAND_SWITCH_WORKSPACE, add_focus_window_command(command_buffer, window->id);
.as.switch_workspace.workspace = window->workspace_id,
};
command_buffer_push(command_buffer, &switch_workspace_cmd);
command_t focus_cmd = {
.type = ZDWM_COMMAND_FOCUS_WINDOW,
.as.focus.window = window->id,
};
command_buffer_push(command_buffer, &focus_cmd);
} }
static output_id_t get_cycled_output(const state_t *state, int32_t delta) { static output_id_t get_cycled_output(const state_t *state, int32_t delta) {
@@ -123,11 +134,7 @@ static void switch_workspace_same_output_by_index(
if (workspace->output_id != output->id) continue; if (workspace->output_id != output->id) continue;
if (count == index) { if (count == index) {
command_t switch_workspace_cmd = { add_switch_workspace_command(command_buffer, workspace->id);
.type = ZDWM_COMMAND_SWITCH_WORKSPACE,
.as.switch_workspace.workspace = workspace->id,
};
command_buffer_push(command_buffer, &switch_workspace_cmd);
return; return;
} }
count++; count++;
@@ -269,11 +276,7 @@ static void cycle_focused_window(
auto target = state_window_at(state, indices[next]); auto target = state_window_at(state, indices[next]);
command_t focus_cmd = { add_focus_window_command(command_buffer, target->id);
.type = ZDWM_COMMAND_FOCUS_WINDOW,
.as.focus.window = target->id,
};
command_buffer_push(command_buffer, &focus_cmd);
command_t raise_cmd = { command_t raise_cmd = {
.type = ZDWM_COMMAND_RAISE_WINDOW, .type = ZDWM_COMMAND_RAISE_WINDOW,
@@ -339,11 +342,7 @@ static void send_window_to_workspace_same_output_by_index(
if (current_workspace->id == target_workspace->id) return; if (current_workspace->id == target_workspace->id) return;
if (data->switch_workspace) { if (data->switch_workspace) {
command_t switch_workspace_command = { add_switch_workspace_command(command_buffer, target_workspace->id);
.type = ZDWM_COMMAND_SWITCH_WORKSPACE,
.as.switch_workspace.workspace = target_workspace->id,
};
command_buffer_push(command_buffer, &switch_workspace_command);
} }
command_t send_window_to_workspace_command = { command_t send_window_to_workspace_command = {
@@ -362,6 +361,8 @@ static void policy_resolve_action(
command_buffer_t *out command_buffer_t *out
) { ) {
switch (action->type) { switch (action->type) {
case ZDWM_ACTION_NONE:
break;
case ZDWM_ACTION_SPAWN: case ZDWM_ACTION_SPAWN:
spawn(action->as.spawn.command); spawn(action->as.spawn.command);
break; break;
@@ -374,6 +375,9 @@ static void policy_resolve_action(
case ZDWM_ACTION_OUTPUT_CYCLE: case ZDWM_ACTION_OUTPUT_CYCLE:
cycle_current_output(ctx->state, action->as.output_cycle.delta, out); cycle_current_output(ctx->state, action->as.output_cycle.delta, out);
break; break;
case ZDWM_ACTION_WORKSPACE_SWITCH:
add_switch_workspace_command(out, action->as.switch_workspace.workspace);
break;
case ZDWM_ACTION_WORKSPACE_SWITCH_SAME_OUTPUT_BY_INDEX: { case ZDWM_ACTION_WORKSPACE_SWITCH_SAME_OUTPUT_BY_INDEX: {
auto index = action->as.workspace_switch_same_output_by_index.index; auto index = action->as.workspace_switch_same_output_by_index.index;
switch_workspace_same_output_by_index(ctx->state, index, out); switch_workspace_same_output_by_index(ctx->state, index, out);
@@ -440,11 +444,7 @@ static void route_key_press(
static void static void
route_pointer_enter(state_t *state, window_id_t window, command_buffer_t *out) { route_pointer_enter(state_t *state, window_id_t window, command_buffer_t *out) {
command_t focus_command = { add_focus_window_command(out, window);
.type = ZDWM_COMMAND_FOCUS_WINDOW,
.as.focus.window = window,
};
command_buffer_push(out, &focus_command);
} }
static workspace_id_t derive_window_workspace(const state_t *state) { static workspace_id_t derive_window_workspace(const state_t *state) {
@@ -511,12 +511,7 @@ static void route_map_request(
const workspace_t *workspace = state_workspace_get(state, workspace_id); const workspace_t *workspace = state_workspace_get(state, workspace_id);
if (!workspace) return; if (!workspace) return;
command_t switch_workspace_cmd = { add_switch_workspace_command(out, workspace_id);
.type = ZDWM_COMMAND_SWITCH_WORKSPACE,
.as.switch_workspace.workspace = workspace_id,
};
command_buffer_push(out, &switch_workspace_cmd);
} }
static void route_window_remove( static void route_window_remove(
@@ -594,19 +589,10 @@ static void route_window_activate_request(
}; };
command_buffer_push(out, &change_window_state_cmd); command_buffer_push(out, &change_window_state_cmd);
} break; } break;
case ZDWM_WINDOW_ACTIVATION_SOURCE_PAGER: { case ZDWM_WINDOW_ACTIVATION_SOURCE_PAGER:
command_t switch_workspace_cmd = { add_switch_workspace_command(out, window->workspace_id);
.type = ZDWM_COMMAND_SWITCH_WORKSPACE, add_focus_window_command(out, window->id);
.as.switch_workspace.workspace = window->workspace_id, break;
};
command_buffer_push(out, &switch_workspace_cmd);
command_t focus_cmd = {
.type = ZDWM_COMMAND_FOCUS_WINDOW,
.as.focus.window = window->id,
};
command_buffer_push(out, &focus_cmd);
} break;
} }
} }