diff --git a/src/backend/x11/backend.c b/src/backend/x11/backend.c index 2bb09ea..60370fb 100644 --- a/src/backend/x11/backend.c +++ b/src/backend/x11/backend.c @@ -466,6 +466,29 @@ find_or_push_configure(window_configure_list_t *configs, xcb_window_t window) { return cfg; } +static void merge_window_configure_params( + backend_t *backend, + const configure_data_t *data +) { + auto cfg = find_or_push_configure(&backend->config_list, data->window); + +#define FIELD_MERGE(MASK, VALUE_FIELD, DATA_FIELD) \ + if (data->changed_fields & (MASK)) { \ + cfg->mask |= (MASK); \ + cfg->value.VALUE_FIELD = data->DATA_FIELD; \ + } + + FIELD_MERGE(ZDWM_CONFIGURE_FIELD_X, x, x); + FIELD_MERGE(ZDWM_CONFIGURE_FIELD_Y, y, y); + FIELD_MERGE(ZDWM_CONFIGURE_FIELD_WIDTH, width, width); + FIELD_MERGE(ZDWM_CONFIGURE_FIELD_HEIGHT, height, height); + FIELD_MERGE(ZDWM_CONFIGURE_FIELD_BORDER_WIDTH, border_width, border_width); + FIELD_MERGE(ZDWM_CONFIGURE_FIELD_SIBLING, sibling, sibling); + FIELD_MERGE(ZDWM_CONFIGURE_FIELD_STACK_MODE, stack_mode, stack_mode); + +#undef FIELD_MERGE +} + static void backend_bind_key(backend_t *backend, const effect_bind_key_t *bind_key) { auto root = backend->screen->root; @@ -477,8 +500,6 @@ static void backend_merge_effects( const effect_t *effects, size_t effect_count ) { - window_configure_list_t *configs = &backend->config_list; - for (size_t i = 0; i < effect_count; ++i) { const effect_t *e = &effects[i]; switch (e->type) { @@ -529,20 +550,9 @@ static void backend_merge_effects( window_set_net_wm_state(backend, window, 0, nullptr); } } break; - case ZDWM_EFFECT_MOVE_WINDOW: { - window_configure_t *cfg = - find_or_push_configure(configs, e->as.move.window); - cfg->mask |= XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y; - cfg->value.x = e->as.move.left_top_point.x; - cfg->value.y = e->as.move.left_top_point.y; - } break; - case ZDWM_EFFECT_RESIZE_WINDOW: { - window_configure_t *cfg = - find_or_push_configure(configs, e->as.resize.window); - cfg->mask |= XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; - cfg->value.width = (uint32_t)e->as.resize.width; - cfg->value.height = (uint32_t)e->as.resize.height; - } break; + case ZDWM_EFFECT_CONFIGURE_WINDOW: + merge_window_configure_params(backend, &e->as.configure); + break; case ZDWM_EFFECT_CHANGE_BORDER_COLOR: { xcb_change_window_attributes_value_list_t value = { .border_pixel = e->as.change_border_color.color->argb @@ -554,12 +564,6 @@ static void backend_merge_effects( &value ); } break; - case ZDWM_EFFECT_CHANGE_BORDER_WIDTH: { - window_configure_t *cfg = - find_or_push_configure(configs, e->as.change_border_width.window); - cfg->mask |= XCB_CONFIG_WINDOW_BORDER_WIDTH; - cfg->value.border_width = e->as.change_border_width.border_width; - } break; case ZDWM_EFFECT_CHANGE_WINDOW_LIST: backend_change_window_list(backend, false, &e->as.change_window_list); break; diff --git a/src/backend/x11/event.c b/src/backend/x11/event.c index da2ed5d..fa61191 100644 --- a/src/backend/x11/event.c +++ b/src/backend/x11/event.c @@ -199,8 +199,27 @@ static bool handle_configure_request( event_t *event, const xcb_configure_request_event_t *xcb_event ) { - event->type = ZDWM_EVENT_CONFIGURE_REQUEST; - /* TODO: */ + event->type = ZDWM_EVENT_CONFIGURE_REQUEST; + auto data = &event->as.configure_request; + data->window = xcb_event->window; + data->changed_fields = 0u; + +#define EXTRACT_FIELD(XCB_MASK, FIELD_MASK, DATA_FIELD, EVENT_FIELD) \ + if (xcb_event->value_mask & XCB_CONFIG_WINDOW_##XCB_MASK) { \ + data->DATA_FIELD = xcb_event->EVENT_FIELD; \ + data->changed_fields |= ZDWM_CONFIGURE_FIELD_##FIELD_MASK; \ + } + + EXTRACT_FIELD(X, X, x, x); + EXTRACT_FIELD(Y, Y, y, y); + EXTRACT_FIELD(WIDTH, WIDTH, width, width); + EXTRACT_FIELD(HEIGHT, HEIGHT, height, height); + EXTRACT_FIELD(BORDER_WIDTH, BORDER_WIDTH, border_width, border_width); + EXTRACT_FIELD(SIBLING, SIBLING, sibling, sibling); + EXTRACT_FIELD(STACK_MODE, STACK_MODE, stack_mode, stack_mode); + +#undef EXTRACT_FIELD + return true; } diff --git a/src/backend/x11/internal.h b/src/backend/x11/internal.h index 2f27550..109afcd 100644 --- a/src/backend/x11/internal.h +++ b/src/backend/x11/internal.h @@ -60,7 +60,7 @@ typedef struct atoms_t { typedef struct window_configure_t { xcb_window_t window; - uint16_t mask; + uint32_t mask; xcb_configure_window_value_list_t value; } window_configure_t; diff --git a/src/core/event.h b/src/core/event.h index 6243582..3c9c5ca 100644 --- a/src/core/event.h +++ b/src/core/event.h @@ -114,23 +114,6 @@ typedef struct window_state_request_event_t { window_state_request_action_t action; } window_state_request_event_t; -typedef enum configure_request_field_t { - ZDWM_CONFIGURE_REQUEST_FIELD_NONE = 0, - ZDWM_CONFIGURE_REQUEST_FIELD_X = 1u << 0, - ZDWM_CONFIGURE_REQUEST_FIELD_Y = 1u << 1, - ZDWM_CONFIGURE_REQUEST_FIELD_WIDTH = 1u << 2, - ZDWM_CONFIGURE_REQUEST_FIELD_HEIGHT = 1u << 3, -} configure_request_field_t; - -typedef struct configure_request_event_t { - window_id_t window; - uint32_t changed_fields; - int32_t x; - int32_t y; - int32_t width; - int32_t height; -} configure_request_event_t; - typedef struct event_t { event_type_t type; union { @@ -145,7 +128,7 @@ typedef struct event_t { window_hints_changed_event_t window_hints_changed; window_activate_request_event_t window_activate_request; window_state_request_event_t window_state_request; - configure_request_event_t configure_request; + configure_data_t configure_request; } as; } event_t; diff --git a/src/core/plan.h b/src/core/plan.h index 0a746a4..0ea86a2 100644 --- a/src/core/plan.h +++ b/src/core/plan.h @@ -14,10 +14,8 @@ typedef enum effect_type_t { ZDWM_EFFECT_MINIMIZE_WINDOW, ZDWM_EFFECT_MAXIMIZE_WINDOW, ZDWM_EFFECT_FULLSCREEN_WINDOW, - ZDWM_EFFECT_MOVE_WINDOW, - ZDWM_EFFECT_RESIZE_WINDOW, + ZDWM_EFFECT_CONFIGURE_WINDOW, ZDWM_EFFECT_CHANGE_BORDER_COLOR, - ZDWM_EFFECT_CHANGE_BORDER_WIDTH, ZDWM_EFFECT_CHANGE_WINDOW_LIST, ZDWM_EFFECT_RESTACK_WINDOWS, ZDWM_EFFECT_BIND_KEY, @@ -43,11 +41,6 @@ typedef struct effect_change_border_color_t { const color_t *color; } effect_change_border_color_t; -typedef struct effect_change_border_width_t { - window_id_t window; - uint32_t border_width; -} effect_change_border_width_t; - typedef struct effect_window_list_t { const window_id_t *windows; size_t count; @@ -74,10 +67,8 @@ typedef struct effect_t { effect_bool_window_t minimize; effect_bool_window_t maximize; effect_bool_window_t fullscreen; - effect_move_window_t move; - effect_resize_window_t resize; + configure_data_t configure; effect_change_border_color_t change_border_color; - effect_change_border_width_t change_border_width; effect_window_list_t change_window_list; effect_window_list_t restack_windows; effect_bind_key_t bind_key; diff --git a/src/core/runtime.c b/src/core/runtime.c index f0902ea..3bf380b 100644 --- a/src/core/runtime.c +++ b/src/core/runtime.c @@ -216,27 +216,26 @@ static void runtime_apply_window_rect( auto need_move = window_need_move(window, rect.x, rect.y); auto need_resize = window_need_resize(window, rect.width, rect.height); + + uint32_t changed_fields = 0u; if (need_move) { - effect_t move_window_effect = { - .type = ZDWM_EFFECT_MOVE_WINDOW, - .as.move = { - .window = window_id, - .left_top_point = {.x = rect.x, .y = rect.y} - } - }; - plan_push_effect(plan, &move_window_effect); + changed_fields |= ZDWM_CONFIGURE_FIELD_X | ZDWM_CONFIGURE_FIELD_Y; } if (need_resize) { - effect_t resize_window_effect = { - .type = ZDWM_EFFECT_RESIZE_WINDOW, - .as.resize = { - .window = window_id, - .width = rect.width, - .height = rect.height, - } - }; - plan_push_effect(plan, &resize_window_effect); + changed_fields |= ZDWM_CONFIGURE_FIELD_WIDTH | ZDWM_CONFIGURE_FIELD_HEIGHT; } + effect_t configure_effect = { + .type = ZDWM_EFFECT_CONFIGURE_WINDOW, + .as.configure = { + .window = window_id, + .x = rect.x, + .y = rect.y, + .width = rect.width, + .height = rect.height, + .changed_fields = changed_fields, + } + }; + plan_push_effect(plan, &configure_effect); if (need_move || need_resize) { state_window_set_frame_rect(state, window_id, rect); diff --git a/src/core/types.h b/src/core/types.h index 08d60f8..782a0bf 100644 --- a/src/core/types.h +++ b/src/core/types.h @@ -79,3 +79,25 @@ typedef enum window_state_request_action_t { ZDWM_WINDOW_STATE_ACTION_REMOVE, ZDWM_WINDOW_STATE_ACTION_TOGGLE, } window_state_request_action_t; + +typedef enum configure_field_t { + ZDWM_CONFIGURE_FIELD_X = 1u << 0, + ZDWM_CONFIGURE_FIELD_Y = 1u << 1, + ZDWM_CONFIGURE_FIELD_WIDTH = 1u << 2, + ZDWM_CONFIGURE_FIELD_HEIGHT = 1u << 3, + ZDWM_CONFIGURE_FIELD_BORDER_WIDTH = 1u << 4, + ZDWM_CONFIGURE_FIELD_SIBLING = 1u << 5, + ZDWM_CONFIGURE_FIELD_STACK_MODE = 1u << 6, +} configure_field_t; + +typedef struct configure_data_t { + window_id_t window; + uint32_t changed_fields; + int32_t x; + int32_t y; + int32_t width; + int32_t height; + uint32_t border_width; + window_id_t sibling; + uint32_t stack_mode; +} configure_data_t;