feat(core+backend/X11): 区分窗口销毁和撤销
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
#include <xcb/randr.h>
|
#include <xcb/randr.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/xcb_aux.h>
|
#include <xcb/xcb_aux.h>
|
||||||
|
#include <xcb/xcb_icccm.h>
|
||||||
#include <xcb/xcb_keysyms.h>
|
#include <xcb/xcb_keysyms.h>
|
||||||
#include <xcb/xfixes.h>
|
#include <xcb/xfixes.h>
|
||||||
#include <xcb/xinerama.h>
|
#include <xcb/xinerama.h>
|
||||||
@@ -494,6 +495,13 @@ static void backend_merge_effects(
|
|||||||
case ZDWM_EFFECT_KILL_WINDOW:
|
case ZDWM_EFFECT_KILL_WINDOW:
|
||||||
window_list_push(&backend->kill, e->as.kill.window);
|
window_list_push(&backend->kill, e->as.kill.window);
|
||||||
break;
|
break;
|
||||||
|
case ZDWM_EFFECT_WITHDRAW_WINDOW:
|
||||||
|
window_set_icccm_wm_state(
|
||||||
|
backend->conn,
|
||||||
|
e->as.withdraw.window,
|
||||||
|
XCB_ICCCM_WM_STATE_WITHDRAWN
|
||||||
|
);
|
||||||
|
break;
|
||||||
case ZDWM_EFFECT_MOVE_WINDOW: {
|
case ZDWM_EFFECT_MOVE_WINDOW: {
|
||||||
window_configure_t *cfg =
|
window_configure_t *cfg =
|
||||||
find_or_push_configure(configs, e->as.move.window);
|
find_or_push_configure(configs, e->as.move.window);
|
||||||
|
|||||||
@@ -173,7 +173,11 @@ static bool handle_unmap_notify(
|
|||||||
) {
|
) {
|
||||||
event->type = ZDWM_EVENT_WINDOW_REMOVE;
|
event->type = ZDWM_EVENT_WINDOW_REMOVE;
|
||||||
event->as.window_remove.window = xcb_event->window;
|
event->as.window_remove.window = xcb_event->window;
|
||||||
event->as.window_remove.reason = ZDWM_WINDOW_REMOVE_WITHDRAWN;
|
if (XCB_EVENT_SENT(xcb_event)) {
|
||||||
|
event->as.window_remove.reason = ZDWM_WINDOW_REMOVE_WITHDRAWN;
|
||||||
|
} else {
|
||||||
|
event->as.window_remove.reason = ZDWM_WINDOW_REMOVE_DESTROY;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -251,7 +255,8 @@ bool backend_next_event(backend_t *backend, event_t *event) {
|
|||||||
uint8_t response_type = XCB_EVENT_RESPONSE_TYPE(raw_event);
|
uint8_t response_type = XCB_EVENT_RESPONSE_TYPE(raw_event);
|
||||||
bool handled = false;
|
bool handled = false;
|
||||||
|
|
||||||
printf("xcb event type: %u\n", response_type);
|
auto label = xcb_event_get_label(response_type);
|
||||||
|
printf("xcb event type: %s[%u]\n", label, response_type);
|
||||||
|
|
||||||
switch (response_type) {
|
switch (response_type) {
|
||||||
#define EVENT(type, handler) \
|
#define EVENT(type, handler) \
|
||||||
|
|||||||
@@ -319,6 +319,27 @@ void window_clean_event_mask(xcb_connection_t *conn, xcb_window_t window) {
|
|||||||
xcb_change_window_attributes_aux(conn, window, change_mask, &value_list);
|
xcb_change_window_attributes_aux(conn, window, change_mask, &value_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void window_set_icccm_wm_state(
|
||||||
|
xcb_connection_t *conn,
|
||||||
|
xcb_window_t window,
|
||||||
|
xcb_icccm_wm_state_t state
|
||||||
|
) {
|
||||||
|
xcb_icccm_wm_hints_t hints;
|
||||||
|
xcb_icccm_wm_hints_set_none(&hints);
|
||||||
|
switch (state) {
|
||||||
|
case XCB_ICCCM_WM_STATE_WITHDRAWN:
|
||||||
|
xcb_icccm_wm_hints_set_withdrawn(&hints);
|
||||||
|
break;
|
||||||
|
case XCB_ICCCM_WM_STATE_NORMAL:
|
||||||
|
xcb_icccm_wm_hints_set_normal(&hints);
|
||||||
|
break;
|
||||||
|
case XCB_ICCCM_WM_STATE_ICONIC:
|
||||||
|
xcb_icccm_wm_hints_set_iconic(&hints);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
xcb_icccm_set_wm_hints(conn, window, &hints);
|
||||||
|
}
|
||||||
|
|
||||||
void window_list_push(window_list_t *window_list, xcb_window_t window) {
|
void window_list_push(window_list_t *window_list, xcb_window_t window) {
|
||||||
xcb_window_t *win =
|
xcb_window_t *win =
|
||||||
array_push(window_list->windows, window_list->count, window_list->capacity);
|
array_push(window_list->windows, window_list->count, window_list->capacity);
|
||||||
|
|||||||
@@ -84,6 +84,11 @@ void window_kill(backend_t *backend, xcb_window_t window);
|
|||||||
void root_set_event_mask(backend_t *backend);
|
void root_set_event_mask(backend_t *backend);
|
||||||
void window_set_event_mask(xcb_connection_t *conn, xcb_window_t window);
|
void window_set_event_mask(xcb_connection_t *conn, xcb_window_t window);
|
||||||
void window_clean_event_mask(xcb_connection_t *conn, xcb_window_t window);
|
void window_clean_event_mask(xcb_connection_t *conn, xcb_window_t window);
|
||||||
|
void window_set_icccm_wm_state(
|
||||||
|
xcb_connection_t *conn,
|
||||||
|
xcb_window_t window,
|
||||||
|
xcb_icccm_wm_state_t state
|
||||||
|
);
|
||||||
|
|
||||||
void window_list_push(window_list_t *window_list, xcb_window_t window);
|
void window_list_push(window_list_t *window_list, xcb_window_t window);
|
||||||
void window_list_reset(window_list_t *window_list);
|
void window_list_reset(window_list_t *window_list);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
typedef enum command_type_t {
|
typedef enum command_type_t {
|
||||||
ZDWM_COMMAND_MANAGE_WINDOW,
|
ZDWM_COMMAND_MANAGE_WINDOW,
|
||||||
ZDWM_COMMAND_UNMANAGE_WINDOW,
|
ZDWM_COMMAND_UNMANAGE_WINDOW,
|
||||||
|
ZDWM_COMMAND_WITHDRAW_WINDOW,
|
||||||
ZDWM_COMMAND_FOCUS_WINDOW,
|
ZDWM_COMMAND_FOCUS_WINDOW,
|
||||||
ZDWM_COMMAND_KILL_WINDOW,
|
ZDWM_COMMAND_KILL_WINDOW,
|
||||||
ZDWM_COMMAND_SWITCH_WORKSPACE,
|
ZDWM_COMMAND_SWITCH_WORKSPACE,
|
||||||
@@ -40,6 +41,7 @@ typedef struct command_t {
|
|||||||
union {
|
union {
|
||||||
manage_window_command_t manage_window;
|
manage_window_command_t manage_window;
|
||||||
only_window_command_t unmanage;
|
only_window_command_t unmanage;
|
||||||
|
only_window_command_t withdraw;
|
||||||
only_window_command_t focus;
|
only_window_command_t focus;
|
||||||
only_window_command_t kill;
|
only_window_command_t kill;
|
||||||
switch_workspace_command_t switch_workspace;
|
switch_workspace_command_t switch_workspace;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ typedef enum effect_type_t {
|
|||||||
ZDWM_EFFECT_UNMAP_WINDOW,
|
ZDWM_EFFECT_UNMAP_WINDOW,
|
||||||
ZDWM_EFFECT_FOCUS_WINDOW,
|
ZDWM_EFFECT_FOCUS_WINDOW,
|
||||||
ZDWM_EFFECT_KILL_WINDOW,
|
ZDWM_EFFECT_KILL_WINDOW,
|
||||||
|
ZDWM_EFFECT_WITHDRAW_WINDOW,
|
||||||
ZDWM_EFFECT_MOVE_WINDOW,
|
ZDWM_EFFECT_MOVE_WINDOW,
|
||||||
ZDWM_EFFECT_RESIZE_WINDOW,
|
ZDWM_EFFECT_RESIZE_WINDOW,
|
||||||
ZDWM_EFFECT_CHANGE_BORDER_COLOR,
|
ZDWM_EFFECT_CHANGE_BORDER_COLOR,
|
||||||
@@ -61,6 +62,7 @@ typedef struct effect_t {
|
|||||||
effect_only_window_id_t unmap;
|
effect_only_window_id_t unmap;
|
||||||
effect_only_window_id_t focus;
|
effect_only_window_id_t focus;
|
||||||
effect_only_window_id_t kill;
|
effect_only_window_id_t kill;
|
||||||
|
effect_only_window_id_t withdraw;
|
||||||
effect_move_window_t move;
|
effect_move_window_t move;
|
||||||
effect_resize_window_t resize;
|
effect_resize_window_t resize;
|
||||||
effect_change_border_color_t change_border_color;
|
effect_change_border_color_t change_border_color;
|
||||||
|
|||||||
@@ -119,11 +119,22 @@ static void route_window_remove(
|
|||||||
const window_t *window = state_window_get(state, e->window);
|
const window_t *window = state_window_get(state, e->window);
|
||||||
if (!window) return;
|
if (!window) return;
|
||||||
|
|
||||||
command_t unmanage_window_cmd = {
|
switch (e->reason) {
|
||||||
.type = ZDWM_COMMAND_UNMANAGE_WINDOW,
|
case ZDWM_WINDOW_REMOVE_WITHDRAWN:
|
||||||
.as.unmanage.window = e->window,
|
command_t withdrawn_window_cmd = {
|
||||||
};
|
.type = ZDWM_COMMAND_WITHDRAW_WINDOW,
|
||||||
command_buffer_push(out, &unmanage_window_cmd);
|
.as.withdraw.window = e->window,
|
||||||
|
};
|
||||||
|
command_buffer_push(out, &withdrawn_window_cmd);
|
||||||
|
break;
|
||||||
|
case ZDWM_WINDOW_REMOVE_DESTROY:
|
||||||
|
command_t unmanage_window_cmd = {
|
||||||
|
.type = ZDWM_COMMAND_UNMANAGE_WINDOW,
|
||||||
|
.as.unmanage.window = e->window,
|
||||||
|
};
|
||||||
|
command_buffer_push(out, &unmanage_window_cmd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void policy_route_event(
|
void policy_route_event(
|
||||||
@@ -232,6 +243,18 @@ static void unmanage_window(state_t *state, window_id_t window, plan_t *plan) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
withdraw_window(const state_t *state, window_id_t window, plan_t *plan) {
|
||||||
|
auto win = state_window_get(state, window);
|
||||||
|
if (!win) return;
|
||||||
|
|
||||||
|
effect_t withdraw_window_effect = {
|
||||||
|
.type = ZDWM_EFFECT_WITHDRAW_WINDOW,
|
||||||
|
.as.withdraw.window = win->id,
|
||||||
|
};
|
||||||
|
plan_push_effect(plan, &withdraw_window_effect);
|
||||||
|
}
|
||||||
|
|
||||||
static void focus_window(state_t *state, window_id_t window, plan_t *plan) {
|
static void focus_window(state_t *state, window_id_t window, plan_t *plan) {
|
||||||
auto win = state_window_get(state, window);
|
auto win = state_window_get(state, window);
|
||||||
if (!win) return;
|
if (!win) return;
|
||||||
@@ -298,6 +321,9 @@ void policy_apply_command(
|
|||||||
case ZDWM_COMMAND_UNMANAGE_WINDOW:
|
case ZDWM_COMMAND_UNMANAGE_WINDOW:
|
||||||
unmanage_window(state, cmd->as.unmanage.window, plan);
|
unmanage_window(state, cmd->as.unmanage.window, plan);
|
||||||
break;
|
break;
|
||||||
|
case ZDWM_COMMAND_WITHDRAW_WINDOW:
|
||||||
|
withdraw_window(state, cmd->as.withdraw.window, plan);
|
||||||
|
break;
|
||||||
case ZDWM_COMMAND_FOCUS_WINDOW:
|
case ZDWM_COMMAND_FOCUS_WINDOW:
|
||||||
focus_window(state, cmd->as.focus.window, plan);
|
focus_window(state, cmd->as.focus.window, plan);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user