refactor(window): 用更通用的尺寸提示(min/max size)替换 fixed_size 标记

This commit is contained in:
2026-06-22 23:22:08 +08:00
parent 9a1e015fc1
commit b71b66921e
12 changed files with 161 additions and 107 deletions

View File

@@ -22,6 +22,7 @@ typedef enum command_type_t {
ZDWM_COMMAND_WINDOW_SET_MINIMIZED,
ZDWM_COMMAND_WINDOW_SET_MAXIMIZED,
ZDWM_COMMAND_WINDOW_SET_FULLSCREEN,
ZDWM_COMMAND_CHANGE_HINTS,
ZDWM_COMMAND_SWITCH_WORKSPACE,
ZDWM_COMMAND_SET_CURRENT_OUTPUT,
ZDWM_COMMAND_SET_LAYOUT,
@@ -110,6 +111,7 @@ typedef struct command_t {
window_bool_state_t minimized;
window_bool_state_t maximized;
window_bool_state_t fullscreen;
hints_data_t hints;
switch_workspace_command_t switch_workspace;
set_current_output_command_t current_output;
set_layout_command_t layout;

View File

@@ -47,12 +47,14 @@ typedef struct window_map_request_event_t {
bool override_redirect;
bool skip_taskbar;
bool urgent;
bool fixed_size;
bool fullscreen;
bool maximized;
bool minimized;
rect_t rect;
zdwm_size_t min_size;
zdwm_size_t max_size;
window_layer_props_t props;
window_metadata_t metadata;
} window_map_request_event_t;
@@ -101,6 +103,7 @@ typedef struct event_t {
window_map_request_event_t window_map_request;
window_remove_event_t window_remove;
window_metadata_change_event_t window_metadata_change;
hints_data_t hints;
window_activate_request_event_t window_activate_request;
window_state_request_event_t window_state_request;
configure_data_t configure_request;

View File

@@ -606,8 +606,9 @@ static void route_map_request(
.maximized = e->maximized,
.minimized = e->minimized,
.urgent = e->urgent,
.fixed_size = e->fixed_size,
.skip_taskbar = e->skip_taskbar,
.min_size = e->min_size,
.max_size = e->max_size,
},
},
};
@@ -690,28 +691,35 @@ static void route_window_metadata_changed(
listeners_notify_window_updated(ctx->listeners, state, window_id);
}
static void route_window_hints_changed(
state_t *state,
const hints_data_t *data,
command_buffer_t *out
) {
auto window = (window_t *)state_window_get(state, data->window);
if (!window) return;
command_t change_hints_cmd = {
.type = ZDWM_COMMAND_CHANGE_HINTS,
.as.hints = *data,
};
command_buffer_push(out, &change_hints_cmd);
}
static void route_window_activate_request(
state_t *state,
const window_activate_request_event_t *e,
command_buffer_t *out
) {
auto window = state_window_get(state, e->window);
auto window = (window_t *)state_window_get(state, e->window);
if (!window) return;
switch (e->source) {
case ZDWM_WINDOW_ACTIVATION_SOURCE_LEGACY:
break;
case ZDWM_WINDOW_ACTIVATION_SOURCE_APPLICATION: {
command_t change_window_state_cmd = {
.type = ZDWM_COMMAND_CHANGE_WINDOW_STATE,
.as.state_change = {
.type = ZDWM_WINDOW_STATE_REQUEST_URGENT,
.window = window->id,
.action = ZDWM_WINDOW_STATE_ACTION_ADD,
}
};
command_buffer_push(out, &change_window_state_cmd);
} break;
case ZDWM_WINDOW_ACTIVATION_SOURCE_APPLICATION:
window->urgent = true;
break;
case ZDWM_WINDOW_ACTIVATION_SOURCE_PAGER:
add_switch_workspace_command(out, window->workspace_id);
add_focus_window_command(out, window->id);
@@ -776,6 +784,8 @@ void policy_route_event(
) {
auto state = ctx->state;
switch (event->type) {
case ZDWM_EVENT_NONE:
break;
case ZDWM_EVENT_KEY_PRESS:
route_key_press(ctx, &event->as.key_press, out);
break;
@@ -800,6 +810,9 @@ void policy_route_event(
case ZDWM_EVENT_WINDOW_METADATA_CHANGED:
route_window_metadata_changed(ctx, &event->as.window_metadata_change);
break;
case ZDWM_EVENT_WINDOW_HINTS_CHANGED:
route_window_hints_changed(state, &event->as.hints, out);
break;
case ZDWM_EVENT_WINDOW_ACTIVATE_REQUEST: {
auto data = &event->as.window_activate_request;
route_window_activate_request(state, data, out);
@@ -811,7 +824,6 @@ void policy_route_event(
auto data = &event->as.configure_request;
route_configure_request(state, data, ctx->layouts, out);
} break;
default:
}
}
@@ -902,12 +914,17 @@ static void manage_window(
auto window_id = window->id;
auto workspace_id = command->workspace;
state_window_set_workspace(state, window_id, workspace_id);
state_window_set_floating(state, window_id, command->floating);
set_foucs_window(ctx, workspace_id, window_id, plan);
plan_push_grab_button_effect(plan, window_id);
push_window_list_effect(state, plan);
listeners_notify_window_added(ctx->listeners, state, window_id);
if (window_should_fix_size(window)) {
state_window_set_floating(state, window_id, true);
} else {
state_window_set_floating(state, window_id, command->floating);
}
auto need_layout = window_need_layout(window);
if (need_layout) {
adjust_layout_windows_border_width(state, ctx->border->width, workspace_id);
@@ -1297,12 +1314,6 @@ static void change_window_state(
case ZDWM_WINDOW_STATE_REQUEST_SKIP_TASKBAR:
value = !window->skip_taskbar;
break;
case ZDWM_WINDOW_STATE_REQUEST_URGENT:
value = !window->urgent;
break;
case ZDWM_WINDOW_STATE_REQUEST_FIXED_SIZE:
value = !window->fixed_size;
break;
}
}
@@ -1320,12 +1331,6 @@ static void change_window_state(
case ZDWM_WINDOW_STATE_REQUEST_SKIP_TASKBAR:
state_window_set_skip_taskbar(state, window->id, value);
break;
case ZDWM_WINDOW_STATE_REQUEST_URGENT:
state_window_set_urgent(state, window->id, value);
break;
case ZDWM_WINDOW_STATE_REQUEST_FIXED_SIZE:
state_window_set_fixed_size(state, window->id, value);
break;
}
listeners_notify_window_updated(ctx->listeners, state, command->window);
@@ -1490,12 +1495,20 @@ static void command_window_set_maximized(
maximize_window(ctx, data->window, data->state, plan);
}
static void command_window_set_fullscreen(
const policy_context_t *ctx,
const window_bool_state_t *data,
plan_t *plan
) {
fullscreen_window(ctx, data->window, data->state, plan);
static void
command_change_hints(state_t *state, hints_data_t *data, plan_t *plan) {
auto window = (window_t *)state_window_get(state, data->window);
if (data->changed_fields & ZDWM_HINT_FIELD_URGENT) {
window->urgent = data->urgent;
}
if (data->changed_fields & ZDWM_HINT_FIELD_SIZE) {
window->max_size = data->max_size;
window->min_size = data->min_size;
auto floating = window->floating;
if (window_should_fix_size(window)) window_set_floating(window, true);
if (floating != window->floating) plan->need_relayout = true;
}
}
static inline void change_current_output(
@@ -1674,8 +1687,13 @@ void policy_apply_command(
case ZDWM_COMMAND_WINDOW_SET_MAXIMIZED:
command_window_set_maximized(ctx, &cmd->as.maximized, plan);
break;
case ZDWM_COMMAND_WINDOW_SET_FULLSCREEN:
command_window_set_fullscreen(ctx, &cmd->as.fullscreen, plan);
case ZDWM_COMMAND_WINDOW_SET_FULLSCREEN: {
auto window = cmd->as.fullscreen.window;
auto state = cmd->as.fullscreen.state;
fullscreen_window(ctx, window, state, plan);
} break;
case ZDWM_COMMAND_CHANGE_HINTS:
command_change_hints(state, &cmd->as.hints, plan);
break;
case ZDWM_COMMAND_SWITCH_WORKSPACE:
switch_workspace(ctx, cmd->as.switch_workspace.workspace, plan);

View File

@@ -328,9 +328,9 @@ const window_t *state_window_add(state_t *state, const window_info_t *info) {
window_set_maximized(window, info->maximized);
window_set_minimized(window, info->minimized);
window_set_urgent(window, info->urgent);
window_set_fixed_size(window, info->fixed_size);
window_set_frame_rect(window, info->frame_rect);
window_set_float_rect(window, info->frame_rect);
window_set_size_hint(window, info->min_size, info->max_size);
window_set_title(window, info->title);
window_set_app_id(window, info->app_id);
window_set_role(window, info->role);
@@ -469,24 +469,6 @@ void state_window_set_sticky(
if (window) window_set_sticky(window, sticky);
}
void state_window_set_urgent(
state_t *state,
window_id_t window_id,
bool urgent
) {
window_t *window = (window_t *)state_window_get(state, window_id);
if (window) window_set_urgent(window, urgent);
}
void state_window_set_fixed_size(
state_t *state,
window_id_t window_id,
bool fixed_size
) {
window_t *window = (window_t *)state_window_get(state, window_id);
if (window) window_set_fixed_size(window, fixed_size);
}
void state_window_set_border_width(
state_t *state,
window_id_t window_id,
@@ -502,7 +484,7 @@ void state_window_set_skip_taskbar(
bool skip_taskbar
) {
window_t *window = (window_t *)state_window_get(state, window_id);
if (window) window_set_skip_taskbar(window, skip_taskbar);
if (window) window->skip_taskbar = skip_taskbar;
}
void state_window_set_float_rect(

View File

@@ -224,16 +224,6 @@ void state_window_set_sticky(
window_id_t window_id,
bool sticky
);
void state_window_set_urgent(
state_t *state,
window_id_t window_id,
bool urgent
);
void state_window_set_fixed_size(
state_t *state,
window_id_t window_id,
bool fixed_size
);
void state_window_set_border_width(
state_t *state,
window_id_t window_id,

View File

@@ -72,8 +72,6 @@ typedef enum window_state_request_type_t {
ZDWM_WINDOW_STATE_REQUEST_MAXIMIZED,
ZDWM_WINDOW_STATE_REQUEST_MINIMIZED,
ZDWM_WINDOW_STATE_REQUEST_SKIP_TASKBAR,
ZDWM_WINDOW_STATE_REQUEST_URGENT,
ZDWM_WINDOW_STATE_REQUEST_FIXED_SIZE,
} window_state_request_type_t;
typedef enum window_state_request_action_t {
@@ -114,6 +112,24 @@ typedef struct only_window_data_t {
window_id_t window;
} only_window_data_t;
typedef enum hint_field_t {
ZDWM_HINT_FIELD_URGENT,
ZDWM_HINT_FIELD_SIZE,
} hint_field_t;
typedef struct zdwm_size_t {
int32_t width;
int32_t height;
} zdwm_size_t;
typedef struct hints_data_t {
window_id_t window;
uint32_t changed_fields;
bool urgent;
zdwm_size_t min_size;
zdwm_size_t max_size;
} hints_data_t;
typedef enum window_interaction_mode_t {
ZDWM_WINDOW_INTERACTION_NONE,
ZDWM_WINDOW_INTERACTION_MOVE,

View File

@@ -49,7 +49,7 @@ void window_set_minimized(window_t *window, bool minimized) {
}
void window_set_floating(window_t *window, bool floating) {
if (!floating && (window->fixed_size || window->sticky)) return;
if (!floating && (window_should_fix_size(window) || window->sticky)) return;
if (floating == window->floating) return;
@@ -67,11 +67,6 @@ void window_set_urgent(window_t *window, bool urgent) {
window->urgent = urgent;
}
void window_set_fixed_size(window_t *window, bool fixed_size) {
window->fixed_size = fixed_size;
if (fixed_size) window_set_floating(window, true);
}
void window_set_skip_taskbar(window_t *window, bool skip_taskbar) {
window->skip_taskbar = skip_taskbar;
}
@@ -84,6 +79,18 @@ void window_set_frame_rect(window_t *window, rect_t rect) {
window->frame_rect = rect;
}
void window_set_size_hint(window_t *window, zdwm_size_t min, zdwm_size_t max) {
window->min_size = min;
window->max_size = max;
if (!window_should_fix_size(window)) return;
auto rect = window->frame_rect;
rect.width = min.width;
rect.height = min.height;
window_set_frame_rect(window, rect);
window_set_floating(window, true);
}
void window_set_title(window_t *window, const char *title) {
p_delete(&window->title);
window->title = p_strdup_nullable(title);
@@ -158,3 +165,9 @@ bool window_should_has_border(const window_t *window) {
if (window->fullscreen || window->maximized) return false;
return window->floating;
}
bool window_should_fix_size(const window_t *window) {
auto max = window->max_size;
auto min = window->min_size;
return max.width == min.width && max.height == min.height;
}

View File

@@ -76,9 +76,11 @@ typedef struct window_t {
bool floating;
bool sticky;
bool urgent;
bool fixed_size;
bool skip_taskbar;
zdwm_size_t min_size;
zdwm_size_t max_size;
/* 几何信息(均为包含边框后的外框矩形) */
rect_t float_rect; /* floating 模式下记忆的外框矩形 */
rect_t frame_rect; /* 当前外框矩形(由 layout 或 float_rect 解析) */
@@ -104,10 +106,10 @@ void window_set_minimized(window_t *window, bool minimized);
void window_set_floating(window_t *window, bool floating);
void window_set_sticky(window_t *window, bool sticky);
void window_set_urgent(window_t *window, bool urgent);
void window_set_fixed_size(window_t *window, bool fixed_size);
void window_set_skip_taskbar(window_t *window, bool skip_taskbar);
void window_set_float_rect(window_t *window, rect_t rect);
void window_set_frame_rect(window_t *window, rect_t rect);
void window_set_size_hint(window_t *window, zdwm_size_t min, zdwm_size_t max);
void window_set_title(window_t *window, const char *title);
void window_set_app_id(window_t *window, const char *app_id);
void window_set_role(window_t *window, const char *role);
@@ -127,3 +129,4 @@ bool window_need_layout(const window_t *window);
bool window_need_move(const window_t *window, int32_t x, int32_t y);
bool window_need_resize(const window_t *window, int32_t width, int32_t height);
bool window_should_has_border(const window_t *window);
bool window_should_fix_size(const window_t *window);

View File

@@ -27,8 +27,10 @@ typedef struct window_info_t {
bool maximized;
bool minimized;
bool urgent;
bool fixed_size;
bool skip_taskbar;
zdwm_size_t min_size;
zdwm_size_t max_size;
} window_info_t;
typedef struct workspace_desc_t {