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 conn = backend->conn;
|
||||||
auto root = backend->screen->root;
|
auto root = backend->screen->root;
|
||||||
auto mask = XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
|
auto mask = XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
|
||||||
XCB_EVENT_MASK_POINTER_MOTION;
|
XCB_EVENT_MASK_POINTER_MOTION;
|
||||||
auto mode = XCB_GRAB_MODE_ASYNC;
|
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;
|
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(
|
static void backend_merge_effects(
|
||||||
@@ -578,7 +578,10 @@ static void backend_merge_effects(
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case ZDWM_EFFECT_START_MOVE_WINDOW:
|
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;
|
break;
|
||||||
case ZDWM_EFFECT_MINIMIZE_WINDOW: {
|
case ZDWM_EFFECT_MINIMIZE_WINDOW: {
|
||||||
auto window = e->as.minimize.window;
|
auto window = e->as.minimize.window;
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ typedef enum command_type_t {
|
|||||||
ZDWM_COMMAND_CHANGE_WINDOW_STATE,
|
ZDWM_COMMAND_CHANGE_WINDOW_STATE,
|
||||||
ZDWM_COMMAND_START_MOVE_WINDOW,
|
ZDWM_COMMAND_START_MOVE_WINDOW,
|
||||||
ZDWM_COMMAND_STOP_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_SEND_TO_WORKSPACE,
|
||||||
ZDWM_COMMAND_WINDOW_SET_FLOATING,
|
ZDWM_COMMAND_WINDOW_SET_FLOATING,
|
||||||
ZDWM_COMMAND_WINDOW_SET_STICKY,
|
ZDWM_COMMAND_WINDOW_SET_STICKY,
|
||||||
@@ -47,7 +49,7 @@ typedef struct window_state_change_command_t {
|
|||||||
typedef struct window_start_move_command_t {
|
typedef struct window_start_move_command_t {
|
||||||
window_id_t window;
|
window_id_t window;
|
||||||
point_t pointer_coordinate;
|
point_t pointer_coordinate;
|
||||||
} window_start_move_command_t;
|
} start_interaction_command_t;
|
||||||
|
|
||||||
typedef struct window_send_to_workspace_command_t {
|
typedef struct window_send_to_workspace_command_t {
|
||||||
window_id_t window;
|
window_id_t window;
|
||||||
@@ -100,7 +102,8 @@ typedef struct command_t {
|
|||||||
only_window_data_t withdraw;
|
only_window_data_t withdraw;
|
||||||
configure_data_t configure;
|
configure_data_t configure;
|
||||||
window_state_change_command_t state_change;
|
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_send_to_workspace_command_t send_to_workspace;
|
||||||
window_bool_state_t floating;
|
window_bool_state_t floating;
|
||||||
window_bool_state_t sticky;
|
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);
|
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(
|
void plan_push_fullscreen_effect(
|
||||||
plan_t *plan,
|
plan_t *plan,
|
||||||
window_id_t window_id,
|
window_id_t window_id,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ typedef enum effect_type_t {
|
|||||||
ZDWM_EFFECT_KILL_WINDOW,
|
ZDWM_EFFECT_KILL_WINDOW,
|
||||||
ZDWM_EFFECT_WITHDRAW_WINDOW,
|
ZDWM_EFFECT_WITHDRAW_WINDOW,
|
||||||
ZDWM_EFFECT_START_MOVE_WINDOW,
|
ZDWM_EFFECT_START_MOVE_WINDOW,
|
||||||
|
ZDWM_EFFECT_START_RESIZE_WINDOW,
|
||||||
ZDWM_EFFECT_MINIMIZE_WINDOW,
|
ZDWM_EFFECT_MINIMIZE_WINDOW,
|
||||||
ZDWM_EFFECT_MAXIMIZE_WINDOW,
|
ZDWM_EFFECT_MAXIMIZE_WINDOW,
|
||||||
ZDWM_EFFECT_FULLSCREEN_WINDOW,
|
ZDWM_EFFECT_FULLSCREEN_WINDOW,
|
||||||
@@ -71,6 +72,7 @@ typedef struct effect_t {
|
|||||||
only_window_data_t kill;
|
only_window_data_t kill;
|
||||||
only_window_data_t withdraw;
|
only_window_data_t withdraw;
|
||||||
only_window_data_t move;
|
only_window_data_t move;
|
||||||
|
only_window_data_t resize;
|
||||||
effect_bool_window_t minimize;
|
effect_bool_window_t minimize;
|
||||||
effect_bool_window_t maximize;
|
effect_bool_window_t maximize;
|
||||||
effect_bool_window_t fullscreen;
|
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_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_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_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(
|
void plan_push_fullscreen_effect(
|
||||||
plan_t *plan,
|
plan_t *plan,
|
||||||
window_id_t window_id,
|
window_id_t window_id,
|
||||||
|
|||||||
@@ -480,6 +480,16 @@ static void route_pointer_press(
|
|||||||
};
|
};
|
||||||
command_buffer_push(out, &start_move_cmd);
|
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(
|
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_t stop_move_cmd = {.type = ZDWM_COMMAND_STOP_MOVE_WINDOW};
|
||||||
command_buffer_push(out, &stop_move_cmd);
|
command_buffer_push(out, &stop_move_cmd);
|
||||||
} break;
|
} 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);
|
command_buffer_push(out, &configure);
|
||||||
} break;
|
} 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(
|
static void start_window_move(
|
||||||
const policy_context_t *ctx,
|
const policy_context_t *ctx,
|
||||||
const window_start_move_command_t *command,
|
const start_interaction_command_t *command,
|
||||||
plan_t *plan
|
plan_t *plan
|
||||||
) {
|
) {
|
||||||
auto window_id = command->window;
|
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(
|
static void send_window_to_workspace(
|
||||||
const policy_context_t *ctx,
|
const policy_context_t *ctx,
|
||||||
const window_send_to_workspace_command_t *command,
|
const window_send_to_workspace_command_t *command,
|
||||||
@@ -1589,7 +1651,11 @@ void policy_apply_command(
|
|||||||
case ZDWM_COMMAND_START_MOVE_WINDOW:
|
case ZDWM_COMMAND_START_MOVE_WINDOW:
|
||||||
start_window_move(ctx, &cmd->as.move, plan);
|
start_window_move(ctx, &cmd->as.move, plan);
|
||||||
break;
|
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_MOVE_WINDOW:
|
||||||
|
case ZDWM_COMMAND_STOP_RESIZE_WINDOW:
|
||||||
plan_push_ungrab_pointer(plan);
|
plan_push_ungrab_pointer(plan);
|
||||||
p_clear(ctx->interaction, 1);
|
p_clear(ctx->interaction, 1);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ typedef struct only_window_data_t {
|
|||||||
typedef enum window_interaction_mode_t {
|
typedef enum window_interaction_mode_t {
|
||||||
ZDWM_WINDOW_INTERACTION_NONE,
|
ZDWM_WINDOW_INTERACTION_NONE,
|
||||||
ZDWM_WINDOW_INTERACTION_MOVE,
|
ZDWM_WINDOW_INTERACTION_MOVE,
|
||||||
|
ZDWM_WINDOW_INTERACTION_RESIZE,
|
||||||
} window_interaction_mode_t;
|
} window_interaction_mode_t;
|
||||||
|
|
||||||
typedef struct window_interaction_state_t {
|
typedef struct window_interaction_state_t {
|
||||||
|
|||||||
Reference in New Issue
Block a user