feat: 添加 MOD4 + 鼠标右键调整窗口大小功能
This commit is contained in:
@@ -538,15 +538,15 @@ static void backend_grab_button(
|
||||
}
|
||||
}
|
||||
|
||||
static void backend_start_move_window(backend_t *backend, xcb_window_t window) {
|
||||
static void backend_grab_pointer(backend_t *backend, cursor_t cursor) {
|
||||
auto conn = backend->conn;
|
||||
auto root = backend->screen->root;
|
||||
auto mask = XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
|
||||
XCB_EVENT_MASK_POINTER_MOTION;
|
||||
auto mode = XCB_GRAB_MODE_ASYNC;
|
||||
auto cursor = cursor_get_xcb_cursor(backend, ZDWM_CURSOR_MOVE);
|
||||
auto xcursor = cursor_get_xcb_cursor(backend, cursor);
|
||||
auto time = XCB_TIME_CURRENT_TIME;
|
||||
xcb_grab_pointer(conn, false, root, mask, mode, mode, root, cursor, time);
|
||||
xcb_grab_pointer(conn, false, root, mask, mode, mode, root, xcursor, time);
|
||||
}
|
||||
|
||||
static void backend_merge_effects(
|
||||
@@ -578,7 +578,10 @@ static void backend_merge_effects(
|
||||
);
|
||||
break;
|
||||
case ZDWM_EFFECT_START_MOVE_WINDOW:
|
||||
backend_start_move_window(backend, e->as.move.window);
|
||||
backend_grab_pointer(backend, ZDWM_CURSOR_MOVE);
|
||||
break;
|
||||
case ZDWM_EFFECT_START_RESIZE_WINDOW:
|
||||
backend_grab_pointer(backend, ZDWM_CURSOR_RESIZE);
|
||||
break;
|
||||
case ZDWM_EFFECT_MINIMIZE_WINDOW: {
|
||||
auto window = e->as.minimize.window;
|
||||
|
||||
@@ -14,6 +14,8 @@ typedef enum command_type_t {
|
||||
ZDWM_COMMAND_CHANGE_WINDOW_STATE,
|
||||
ZDWM_COMMAND_START_MOVE_WINDOW,
|
||||
ZDWM_COMMAND_STOP_MOVE_WINDOW,
|
||||
ZDWM_COMMAND_START_RESIZE_WINDOW,
|
||||
ZDWM_COMMAND_STOP_RESIZE_WINDOW,
|
||||
ZDWM_COMMAND_WINDOW_SEND_TO_WORKSPACE,
|
||||
ZDWM_COMMAND_WINDOW_SET_FLOATING,
|
||||
ZDWM_COMMAND_WINDOW_SET_STICKY,
|
||||
@@ -47,7 +49,7 @@ typedef struct window_state_change_command_t {
|
||||
typedef struct window_start_move_command_t {
|
||||
window_id_t window;
|
||||
point_t pointer_coordinate;
|
||||
} window_start_move_command_t;
|
||||
} start_interaction_command_t;
|
||||
|
||||
typedef struct window_send_to_workspace_command_t {
|
||||
window_id_t window;
|
||||
@@ -100,7 +102,8 @@ typedef struct command_t {
|
||||
only_window_data_t withdraw;
|
||||
configure_data_t configure;
|
||||
window_state_change_command_t state_change;
|
||||
window_start_move_command_t move;
|
||||
start_interaction_command_t move;
|
||||
start_interaction_command_t resize;
|
||||
window_send_to_workspace_command_t send_to_workspace;
|
||||
window_bool_state_t floating;
|
||||
window_bool_state_t sticky;
|
||||
|
||||
@@ -110,6 +110,16 @@ void plan_push_move_effect(plan_t *plan, window_id_t window_id) {
|
||||
plan_push_effect(plan, &effect);
|
||||
}
|
||||
|
||||
void plan_push_resize_effect(plan_t *plan, window_id_t window_id) {
|
||||
if (window_id_invalid(window_id)) return;
|
||||
|
||||
effect_t effect = {
|
||||
.type = ZDWM_EFFECT_START_RESIZE_WINDOW,
|
||||
.as.resize.window = window_id,
|
||||
};
|
||||
plan_push_effect(plan, &effect);
|
||||
}
|
||||
|
||||
void plan_push_fullscreen_effect(
|
||||
plan_t *plan,
|
||||
window_id_t window_id,
|
||||
|
||||
@@ -13,6 +13,7 @@ typedef enum effect_type_t {
|
||||
ZDWM_EFFECT_KILL_WINDOW,
|
||||
ZDWM_EFFECT_WITHDRAW_WINDOW,
|
||||
ZDWM_EFFECT_START_MOVE_WINDOW,
|
||||
ZDWM_EFFECT_START_RESIZE_WINDOW,
|
||||
ZDWM_EFFECT_MINIMIZE_WINDOW,
|
||||
ZDWM_EFFECT_MAXIMIZE_WINDOW,
|
||||
ZDWM_EFFECT_FULLSCREEN_WINDOW,
|
||||
@@ -71,6 +72,7 @@ typedef struct effect_t {
|
||||
only_window_data_t kill;
|
||||
only_window_data_t withdraw;
|
||||
only_window_data_t move;
|
||||
only_window_data_t resize;
|
||||
effect_bool_window_t minimize;
|
||||
effect_bool_window_t maximize;
|
||||
effect_bool_window_t fullscreen;
|
||||
@@ -102,6 +104,7 @@ void plan_push_focus_effect(plan_t *plan, window_id_t window_id);
|
||||
void plan_push_kill_effect(plan_t *plan, window_id_t window_id);
|
||||
void plan_push_withdraw_effect(plan_t *plan, window_id_t window_id);
|
||||
void plan_push_move_effect(plan_t *plan, window_id_t window_id);
|
||||
void plan_push_resize_effect(plan_t *plan, window_id_t window_id);
|
||||
void plan_push_fullscreen_effect(
|
||||
plan_t *plan,
|
||||
window_id_t window_id,
|
||||
|
||||
@@ -480,6 +480,16 @@ static void route_pointer_press(
|
||||
};
|
||||
command_buffer_push(out, &start_move_cmd);
|
||||
}
|
||||
if (data->button == ZDWM_BUTTON_RIGHT && data->modifiers == ZDWM_MOD_4) {
|
||||
command_t start_resize_cmd = {
|
||||
.type = ZDWM_COMMAND_START_RESIZE_WINDOW,
|
||||
.as.resize = {
|
||||
.window = window_id,
|
||||
.pointer_coordinate = data->root,
|
||||
}
|
||||
};
|
||||
command_buffer_push(out, &start_resize_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
static void route_pointer_release(
|
||||
@@ -494,6 +504,10 @@ static void route_pointer_release(
|
||||
command_t stop_move_cmd = {.type = ZDWM_COMMAND_STOP_MOVE_WINDOW};
|
||||
command_buffer_push(out, &stop_move_cmd);
|
||||
} break;
|
||||
case ZDWM_WINDOW_INTERACTION_RESIZE: {
|
||||
command_t stop_resize_cmd = {.type = ZDWM_COMMAND_STOP_RESIZE_WINDOW};
|
||||
command_buffer_push(out, &stop_resize_cmd);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,6 +537,28 @@ static void route_pointer_motion(
|
||||
};
|
||||
command_buffer_push(out, &configure);
|
||||
} break;
|
||||
case ZDWM_WINDOW_INTERACTION_RESIZE: {
|
||||
auto rect = interaction->origin_rect;
|
||||
auto start = interaction->start_coordinate;
|
||||
auto end = data->root;
|
||||
|
||||
auto width = rect.width + (end.x - start.x);
|
||||
auto height = rect.height + (end.y - start.y);
|
||||
width = MAX(width, 10);
|
||||
height = MAX(height, 10);
|
||||
|
||||
command_t configure_cmd = {
|
||||
.type = ZDWM_COMMAND_CONFIGURE_WINDOW,
|
||||
.as.configure = {
|
||||
.window = interaction->window,
|
||||
.changed_fields =
|
||||
ZDWM_CONFIGURE_FIELD_WIDTH | ZDWM_CONFIGURE_FIELD_HEIGHT,
|
||||
.width = width,
|
||||
.height = height,
|
||||
}
|
||||
};
|
||||
command_buffer_push(out, &configure_cmd);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1297,7 +1333,7 @@ static void change_window_state(
|
||||
|
||||
static void start_window_move(
|
||||
const policy_context_t *ctx,
|
||||
const window_start_move_command_t *command,
|
||||
const start_interaction_command_t *command,
|
||||
plan_t *plan
|
||||
) {
|
||||
auto window_id = command->window;
|
||||
@@ -1314,6 +1350,32 @@ static void start_window_move(
|
||||
};
|
||||
}
|
||||
|
||||
static void start_window_resize(
|
||||
const policy_context_t *ctx,
|
||||
const start_interaction_command_t *command,
|
||||
plan_t *plan
|
||||
) {
|
||||
auto window_id = command->window;
|
||||
auto window = state_window_get(ctx->state, window_id);
|
||||
if (!window) return;
|
||||
|
||||
auto frame_rect = window->frame_rect;
|
||||
|
||||
point_t pointer_position = {
|
||||
.x = frame_rect.x + frame_rect.width,
|
||||
.y = frame_rect.y + frame_rect.height,
|
||||
};
|
||||
|
||||
plan_push_resize_effect(plan, window_id);
|
||||
|
||||
*ctx->interaction = (window_interaction_state_t){
|
||||
.mode = ZDWM_WINDOW_INTERACTION_RESIZE,
|
||||
.window = window_id,
|
||||
.start_coordinate = pointer_position,
|
||||
.origin_rect = frame_rect,
|
||||
};
|
||||
}
|
||||
|
||||
static void send_window_to_workspace(
|
||||
const policy_context_t *ctx,
|
||||
const window_send_to_workspace_command_t *command,
|
||||
@@ -1589,7 +1651,11 @@ void policy_apply_command(
|
||||
case ZDWM_COMMAND_START_MOVE_WINDOW:
|
||||
start_window_move(ctx, &cmd->as.move, plan);
|
||||
break;
|
||||
case ZDWM_COMMAND_START_RESIZE_WINDOW:
|
||||
start_window_resize(ctx, &cmd->as.resize, plan);
|
||||
break;
|
||||
case ZDWM_COMMAND_STOP_MOVE_WINDOW:
|
||||
case ZDWM_COMMAND_STOP_RESIZE_WINDOW:
|
||||
plan_push_ungrab_pointer(plan);
|
||||
p_clear(ctx->interaction, 1);
|
||||
break;
|
||||
|
||||
@@ -117,6 +117,7 @@ typedef struct only_window_data_t {
|
||||
typedef enum window_interaction_mode_t {
|
||||
ZDWM_WINDOW_INTERACTION_NONE,
|
||||
ZDWM_WINDOW_INTERACTION_MOVE,
|
||||
ZDWM_WINDOW_INTERACTION_RESIZE,
|
||||
} window_interaction_mode_t;
|
||||
|
||||
typedef struct window_interaction_state_t {
|
||||
|
||||
Reference in New Issue
Block a user