diff --git a/src/backend/x11/event.c b/src/backend/x11/event.c index 62101bd..4662354 100644 --- a/src/backend/x11/event.c +++ b/src/backend/x11/event.c @@ -51,27 +51,32 @@ static bool derive_skip_taskbar( return false; } -static window_geometry_mode_t geometry_mode_from_hints( - const xcb_icccm_wm_hints_t *hints -) { - if (hints->initial_state == XCB_ICCCM_WM_STATE_ICONIC) - return ZDWM_GEOMETRY_MINIMIZED; - return ZDWM_GEOMETRY_NORMAL; +static bool minimized_from_hints(const xcb_icccm_wm_hints_t *hints) { + return hints->initial_state == XCB_ICCCM_WM_STATE_ICONIC; } -static window_geometry_mode_t geometry_mode_from_states( +static bool maximized_from_states( const atoms_t *atoms, const xcb_atom_t *state_atoms, uint32_t state_count ) { for (uint32_t i = 0; i < state_count; i++) { - if (state_atoms[i] == atoms->_NET_WM_STATE_FULLSCREEN) - return ZDWM_GEOMETRY_FULLSCREEN; if (state_atoms[i] == atoms->_NET_WM_STATE_MAXIMIZED_VERT || state_atoms[i] == atoms->_NET_WM_STATE_MAXIMIZED_HORZ) - return ZDWM_GEOMETRY_MAXIMIZED; + return true; } - return ZDWM_GEOMETRY_NORMAL; + return false; +} + +static bool fullscreen_from_states( + const atoms_t *atoms, + const xcb_atom_t *state_atoms, + uint32_t state_count +) { + for (uint32_t i = 0; i < state_count; i++) { + if (state_atoms[i] == atoms->_NET_WM_STATE_FULLSCREEN) return true; + } + return false; } static bool urgent_from_states( @@ -98,7 +103,6 @@ static bool handle_map_request( window_map_request_event_t *ev = &event->as.window_map_request; ev->window = (window_id_t)window; ev->transient_for = window_get_transient_for(backend, window); - ev->geometry_mode = ZDWM_GEOMETRY_NORMAL; xcb_get_window_attributes_reply_t *wa = window_get_attributes(backend, window); @@ -108,8 +112,8 @@ static bool handle_map_request( xcb_icccm_wm_hints_t wm_hints = {0}; if (window_get_wm_hints(backend, window, &wm_hints)) { - ev->urgent = (bool)xcb_icccm_wm_hints_get_urgency(&wm_hints); - ev->geometry_mode = geometry_mode_from_hints(&wm_hints); + ev->urgent = (bool)xcb_icccm_wm_hints_get_urgency(&wm_hints); + ev->minimized = minimized_from_hints(&wm_hints); } if (!window_get_fixed_size(backend, window, &ev->fixed_size)) return false; @@ -128,12 +132,9 @@ static bool handle_map_request( return false; } - if (ev->geometry_mode == ZDWM_GEOMETRY_NORMAL && state_atoms) { - ev->geometry_mode = - geometry_mode_from_states(atoms, state_atoms, state_count); - } - if (state_atoms) { + ev->maximized = maximized_from_states(atoms, state_atoms, state_count); + ev->fullscreen = fullscreen_from_states(atoms, state_atoms, state_count); ev->skip_taskbar = derive_skip_taskbar(atoms, state_atoms, state_count); ev->props.states = derive_window_states( atoms, @@ -409,18 +410,16 @@ static bool handle_client_message( data->action = ZDWM_WINDOW_STATE_ACTION_TOGGLE; break; } - auto properties = &xcb_event->data.data32[1]; - uint32_t count = 2; - auto geometry_mode = geometry_mode_from_states(atoms, properties, count); - switch (geometry_mode) { - case ZDWM_GEOMETRY_FULLSCREEN: - data->type = ZDWM_WINDOW_STATE_REQUEST_FULLSCREEN; - return true; - case ZDWM_GEOMETRY_MAXIMIZED: + auto properties = &xcb_event->data.data32[1]; + uint32_t count = 2; + + if (maximized_from_states(atoms, properties, count)) { data->type = ZDWM_WINDOW_STATE_REQUEST_MAXIMIZED; return true; - case ZDWM_GEOMETRY_MINIMIZED: - case ZDWM_GEOMETRY_NORMAL: + } + if (fullscreen_from_states(atoms, properties, count)) { + data->type = ZDWM_WINDOW_STATE_REQUEST_FULLSCREEN; + return true; } if (derive_skip_taskbar(atoms, properties, count)) { diff --git a/src/core/event.h b/src/core/event.h index ab09735..a2b7adf 100644 --- a/src/core/event.h +++ b/src/core/event.h @@ -53,7 +53,9 @@ typedef struct window_map_request_event_t { bool skip_taskbar; bool urgent; bool fixed_size; - window_geometry_mode_t geometry_mode; + bool fullscreen; + bool maximized; + bool minimized; rect_t rect; window_layer_props_t props; diff --git a/src/core/policy.c b/src/core/policy.c index 18ed02b..f88d94d 100644 --- a/src/core/policy.c +++ b/src/core/policy.c @@ -77,11 +77,13 @@ static void route_map_request( .class_name = e->metadata.class_name, .instance_name = e->metadata.instance_name, - .geometry_mode = e->geometry_mode, - .layer_type = layer_type, - .urgent = e->urgent, - .fixed_size = e->fixed_size, - .skip_taskbar = e->skip_taskbar, + .layer_type = layer_type, + .fullscreen = e->fullscreen, + .maximized = e->maximized, + .minimized = e->minimized, + .urgent = e->urgent, + .fixed_size = e->fixed_size, + .skip_taskbar = e->skip_taskbar, }, }, }; @@ -93,15 +95,9 @@ static void route_map_request( if (action.workspace != ZDWM_WORKSPACE_ID_INVALID) { data->workspace = action.workspace; } - if (action.floating) { - data->floating = true; - } - - if (action.fullscreen) { - data->info.geometry_mode = ZDWM_GEOMETRY_FULLSCREEN; - } else if (action.maximize) { - data->info.geometry_mode = ZDWM_GEOMETRY_MAXIMIZED; - } + if (action.floating) data->floating = true; + if (action.fullscreen) data->info.fullscreen = true; + if (action.maximize) data->info.maximized = true; } command_buffer_push(out, &manage_window_cmd); @@ -436,22 +432,17 @@ static void fullscreen_window( auto window = state_window_get(state, window_id); if (!window) return; - if ((value && window->geometry_mode == ZDWM_GEOMETRY_FULLSCREEN) || - (!value && window->geometry_mode != ZDWM_GEOMETRY_FULLSCREEN)) { - return; - } + if (window->fullscreen == value) return; - state_window_set_border_width(state, window_id, 0); plan_push_fullscreen_effect(plan, window_id, value); + state_window_set_fullscreen(state, window_id, value); if (value) { - state_window_set_geometry_mode(state, window_id, ZDWM_GEOMETRY_FULLSCREEN); state_window_set_border_width(state, window_id, 0); if (window->floating) { state_window_set_float_rect(state, window_id, window->frame_rect); } } else { - state_window_set_geometry_mode(state, window_id, ZDWM_GEOMETRY_NORMAL); state_window_set_border_width(state, window_id, ctx->border->width); if (window->floating) { state_window_set_frame_rect(state, window_id, window->float_rect); @@ -474,22 +465,17 @@ static void maximize_window( auto window = state_window_get(state, window_id); if (!window) return; - if ((value && window->geometry_mode == ZDWM_GEOMETRY_MAXIMIZED) || - (!value && window->geometry_mode != ZDWM_GEOMETRY_MAXIMIZED)) { - return; - } + if (window->maximized == value) return; - state_window_set_border_width(state, window_id, 0); plan_push_maximize_effect(plan, window_id, value); + state_window_set_maximized(state, window_id, value); if (value) { - state_window_set_geometry_mode(state, window_id, ZDWM_GEOMETRY_MAXIMIZED); state_window_set_border_width(state, window_id, 0); if (window->floating) { state_window_set_float_rect(state, window_id, window->frame_rect); } } else { - state_window_set_geometry_mode(state, window_id, ZDWM_GEOMETRY_NORMAL); state_window_set_border_width(state, window_id, ctx->border->width); if (window->floating) { state_window_set_frame_rect(state, window_id, window->float_rect); @@ -511,19 +497,16 @@ static void minimize_window( auto window = state_window_get(state, window_id); if (!window) return; - if ((value && window->geometry_mode == ZDWM_GEOMETRY_MINIMIZED) || - (!value && window->geometry_mode != ZDWM_GEOMETRY_MINIMIZED)) { - return; - } + if (window->minimized == value) return; plan_push_minimize_effect(plan, window_id, value); + state_window_set_minimized(state, window_id, value); if (value) { plan_push_unmap_effect(plan, window_id); auto workspace = state_workspace_get(state, window->workspace_id); auto old_focused_window_id = workspace->focused_window_id; - state_window_set_geometry_mode(state, window_id, ZDWM_GEOMETRY_MINIMIZED); auto new_focused_window_id = workspace->focused_window_id; if (old_focused_window_id != new_focused_window_id) { auto color = &ctx->border->normal_color; @@ -533,7 +516,6 @@ static void minimize_window( plan_push_change_border_color_effect(plan, new_focused_window_id, color); } } else { - state_window_set_geometry_mode(state, window_id, ZDWM_GEOMETRY_NORMAL); plan_push_map_effect(plan, window_id); set_foucs_window(ctx, window->workspace_id, window_id, plan); } @@ -564,13 +546,22 @@ static void change_window_state( case ZDWM_WINDOW_STATE_ACTION_TOGGLE: switch (command->type) { case ZDWM_WINDOW_STATE_REQUEST_FULLSCREEN: - value = !(window->geometry_mode == ZDWM_GEOMETRY_FULLSCREEN); + value = !window->fullscreen; break; case ZDWM_WINDOW_STATE_REQUEST_MAXIMIZED: - value = !(window->geometry_mode == ZDWM_GEOMETRY_MAXIMIZED); + value = !window->maximized; break; case ZDWM_WINDOW_STATE_REQUEST_MINIMIZED: - value = !(window->geometry_mode == ZDWM_GEOMETRY_MINIMIZED); + value = !window->minimized; + break; + 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; } } @@ -585,6 +576,16 @@ static void change_window_state( case ZDWM_WINDOW_STATE_REQUEST_MINIMIZED: minimize_window(ctx, window->id, value, plan); break; + /* TODO: 下面三个可能需要添加处理,尤其是 fixed_size 和 floating 相关 */ + 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; } } diff --git a/src/core/runtime.c b/src/core/runtime.c index 6ca98a4..8163d31 100644 --- a/src/core/runtime.c +++ b/src/core/runtime.c @@ -173,13 +173,13 @@ static const layout_result_t *runtime_layout_calc(runtime_t *runtime) { window_id_t *window_id_slot = array_push(window_ids, window_count, window_list_capacity); *window_id_slot = window->id; - } else if (window->geometry_mode == ZDWM_GEOMETRY_FULLSCREEN) { + } else if (window->fullscreen) { layout_item_t item = { .window_id = window->id, .rect = output->geometry, }; layout_result_push(result, item); - } else if (window->geometry_mode == ZDWM_GEOMETRY_MAXIMIZED) { + } else if (window->maximized) { layout_item_t item = { .window_id = window->id, .rect = output->workarea, diff --git a/src/core/state.c b/src/core/state.c index 583f568..532940c 100644 --- a/src/core/state.c +++ b/src/core/state.c @@ -338,7 +338,9 @@ const window_t *state_window_add(state_t *state, const window_info_t *info) { window->layer = info->layer_type; } - window_set_geometry_mode(window, info->geometry_mode); + window_set_fullscreen(window, info->fullscreen); + 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); @@ -435,20 +437,31 @@ void state_window_set_workspace( state_workspace_adjust_focused_window(state, workspace_id); } -void state_window_set_geometry_mode( +void state_window_set_fullscreen( state_t *state, window_id_t window_id, - window_geometry_mode_t geometry_mode + bool fullscreen ) { - window_t *window = (window_t *)state_window_get(state, window_id); - if (window) window_set_geometry_mode(window, geometry_mode); + auto window = (window_t *)state_window_get(state, window_id); + if (window) window_set_fullscreen(window, fullscreen); +} - if (geometry_mode != ZDWM_GEOMETRY_MINIMIZED) return; +void state_window_set_maximized( + state_t *state, + window_id_t window_id, + bool maximized +) { + auto window = (window_t *)state_window_get(state, window_id); + if (window) window_set_maximized(window, maximized); +} - auto workspace = state_workspace_get(state, window->workspace_id); - if (workspace->focused_window_id == window_id) { - state_workspace_adjust_focused_window(state, window->workspace_id); - } +void state_window_set_minimized( + state_t *state, + window_id_t window_id, + bool minimized +) { + auto window = (window_t *)state_window_get(state, window_id); + if (window) window_set_minimized(window, minimized); } void state_window_set_floating( diff --git a/src/core/state.h b/src/core/state.h index 2686975..6dc17de 100644 --- a/src/core/state.h +++ b/src/core/state.h @@ -177,10 +177,20 @@ void state_window_set_workspace( window_id_t window_id, workspace_id_t workspace_id ); -void state_window_set_geometry_mode( +void state_window_set_fullscreen( state_t *state, window_id_t window_id, - window_geometry_mode_t geometry_mode + bool fullscreen +); +void state_window_set_maximized( + state_t *state, + window_id_t window_id, + bool maximized +); +void state_window_set_minimized( + state_t *state, + window_id_t window_id, + bool minimized ); void state_window_set_floating( state_t *state, diff --git a/src/core/types.h b/src/core/types.h index b325569..8f258c5 100644 --- a/src/core/types.h +++ b/src/core/types.h @@ -29,13 +29,6 @@ typedef struct point_t { int32_t y; } point_t; -typedef enum window_geometry_mode_t { - ZDWM_GEOMETRY_NORMAL, - ZDWM_GEOMETRY_MAXIMIZED, - ZDWM_GEOMETRY_FULLSCREEN, - ZDWM_GEOMETRY_MINIMIZED, -} window_geometry_mode_t; - typedef enum focus_direction_t { ZDWM_FOCUS_PREV, ZDWM_FOCUS_NEXT, diff --git a/src/core/window.c b/src/core/window.c index b3ab415..7bcd540 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -36,11 +36,16 @@ void window_metadata_cleanup(window_metadata_t *metadata) { p_delete(&metadata->instance_name); } -void window_set_geometry_mode( - window_t *window, - window_geometry_mode_t geometry_mode -) { - window->geometry_mode = geometry_mode; +void window_set_fullscreen(window_t *window, bool fullscreen) { + window->fullscreen = fullscreen; +} + +void window_set_maximized(window_t *window, bool maximized) { + window->maximized = maximized; +} + +void window_set_minimized(window_t *window, bool minimized) { + window->minimized = minimized; } void window_set_floating(window_t *window, bool floating) { @@ -64,6 +69,10 @@ void window_set_fixed_size(window_t *window, bool 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; +} + void window_set_float_rect(window_t *window, rect_t rect) { window->float_rect = rect; } @@ -101,10 +110,6 @@ void window_set_border_width(window_t *window, uint32_t border_width) { window->border_width = border_width; } -void window_set_skip_taskbar(window_t *window, bool skip_taskbar) { - window->skip_taskbar = skip_taskbar; -} - void window_take_metadata( window_t *window, window_metadata_t *metadata, @@ -130,19 +135,13 @@ void window_take_metadata( bool window_need_layout(const window_t *window) { if (window->floating) return false; - switch (window->geometry_mode) { - case ZDWM_GEOMETRY_FULLSCREEN: - case ZDWM_GEOMETRY_MAXIMIZED: - case ZDWM_GEOMETRY_MINIMIZED: + if (window->fullscreen || window->maximized || window->minimized) { return false; - default: } return true; } -bool window_need_resize(const window_t *window, int32_t width, int32_t height); - bool window_need_move(const window_t *window, int32_t x, int32_t y) { return window->frame_rect.x != x || window->frame_rect.y != y; } @@ -153,12 +152,6 @@ bool window_need_resize(const window_t *window, int32_t width, int32_t height) { } bool window_should_has_border(const window_t *window) { - switch (window->geometry_mode) { - case ZDWM_GEOMETRY_MAXIMIZED: - case ZDWM_GEOMETRY_FULLSCREEN: - return false; - case ZDWM_GEOMETRY_NORMAL: - case ZDWM_GEOMETRY_MINIMIZED: - } + if (window->fullscreen || window->maximized) return false; return window->floating; } diff --git a/src/core/window.h b/src/core/window.h index a87ecc8..0b30e41 100644 --- a/src/core/window.h +++ b/src/core/window.h @@ -70,11 +70,14 @@ typedef struct window_t { workspace_id_t workspace_id; window_layer_type_t layer; - window_geometry_mode_t geometry_mode; + bool fullscreen; + bool maximized; + bool minimized; bool floating; bool sticky; bool urgent; bool fixed_size; + bool skip_taskbar; /* 几何信息(均为包含边框后的外框矩形) */ rect_t float_rect; /* floating 模式下记忆的外框矩形 */ @@ -88,7 +91,6 @@ typedef struct window_t { char *instance_name; uint32_t border_width; - bool skip_taskbar; } window_t; window_layer_type_t window_classify_layer(const window_layer_props_t *props); @@ -96,14 +98,14 @@ window_layer_type_t window_classify_layer(const window_layer_props_t *props); void window_layer_props_cleanup(window_layer_props_t *props); void window_metadata_cleanup(window_metadata_t *metadata); -void window_set_geometry_mode( - window_t *window, - window_geometry_mode_t geometry_mode -); +void window_set_fullscreen(window_t *window, bool fullscreen); +void window_set_maximized(window_t *window, bool maximized); +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_title(window_t *window, const char *title); @@ -112,7 +114,6 @@ void window_set_role(window_t *window, const char *role); void window_set_class(window_t *window, const char *class_name); void window_set_instance(window_t *window, const char *instance_name); void window_set_border_width(window_t *window, uint32_t border_width); -void window_set_skip_taskbar(window_t *window, bool skip_taskbar); void window_take_metadata( window_t *window, window_metadata_t *metadata, diff --git a/src/core/wm_desc.h b/src/core/wm_desc.h index 16d50a3..272430c 100644 --- a/src/core/wm_desc.h +++ b/src/core/wm_desc.h @@ -22,8 +22,10 @@ typedef struct window_info_t { const char *class_name; const char *instance_name; - window_geometry_mode_t geometry_mode; window_layer_type_t layer_type; + bool fullscreen; + bool maximized; + bool minimized; bool urgent; bool fixed_size; bool skip_taskbar;