调整数据类型和接口函数命名规范
This commit is contained in:
@@ -7,6 +7,7 @@ set(CMAKE_C_EXTENSIONS ON)
|
||||
|
||||
set(APP_NAME "zdwm")
|
||||
set(SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
set(INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
set(BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
add_compile_definitions(LOG_FILE="$ENV{HOME}/${APP_NAME}-log.txt")
|
||||
@@ -82,6 +83,7 @@ pkg_check_modules(deps REQUIRED
|
||||
|
||||
target_include_directories(${APP_NAME} SYSTEM
|
||||
PRIVATE ${deps_INCLUDE_DIRS}
|
||||
PRIVATE ${INCLUDE_DIR}
|
||||
)
|
||||
target_include_directories(${APP_NAME}
|
||||
PRIVATE ${SOURCE_DIR}
|
||||
|
||||
@@ -5,18 +5,17 @@
|
||||
|
||||
#include "core/backend.h"
|
||||
#include "core/types.h"
|
||||
#include "core/wm_desc.h"
|
||||
#include "utils.h"
|
||||
|
||||
static inline int32_t right(wm_rect_t a) { return a.x + a.width; }
|
||||
static inline int32_t bottom(wm_rect_t a) { return a.y + a.height; }
|
||||
static inline bool fully_contains(wm_rect_t outer, wm_rect_t inner) {
|
||||
static inline int32_t right(rect_t a) { return a.x + a.width; }
|
||||
static inline int32_t bottom(rect_t a) { return a.y + a.height; }
|
||||
static inline bool fully_contains(rect_t outer, rect_t inner) {
|
||||
return inner.x >= outer.x && inner.y >= outer.y &&
|
||||
right(inner) <= right(outer) && bottom(inner) <= bottom(outer);
|
||||
}
|
||||
|
||||
wm_backend_detect_t *output_remove_duplication(const wm_output_info_t *output,
|
||||
const size_t count) {
|
||||
backend_detect_t *output_remove_duplication(const output_info_t *output,
|
||||
const size_t count) {
|
||||
if (!output || count < 1) return nullptr;
|
||||
|
||||
bool *remove = p_new(bool, count);
|
||||
@@ -42,14 +41,14 @@ wm_backend_detect_t *output_remove_duplication(const wm_output_info_t *output,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
wm_output_info_t *list = p_new(wm_output_info_t, amount);
|
||||
output_info_t *list = p_new(output_info_t, amount);
|
||||
amount = 0;
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
if (remove[i]) continue;
|
||||
list[amount++] = output[i];
|
||||
}
|
||||
p_delete(&remove);
|
||||
wm_backend_detect_t *detect = p_new(wm_backend_detect_t, 1);
|
||||
backend_detect_t *detect = p_new(backend_detect_t, 1);
|
||||
detect->outputs = list;
|
||||
detect->output_count = amount;
|
||||
return detect;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "core/backend.h"
|
||||
#include "core/wm_desc.h"
|
||||
#include "core/types.h"
|
||||
|
||||
wm_backend_detect_t *output_remove_duplication(const wm_output_info_t *output,
|
||||
backend_detect_t *output_remove_duplication(const output_info_t *output,
|
||||
const size_t count);
|
||||
|
||||
@@ -12,17 +12,17 @@
|
||||
#include <xcb/xproto.h>
|
||||
|
||||
#include "backend/output_utils.h"
|
||||
#include "core/wm_desc.h"
|
||||
#include "core/types.h"
|
||||
#include "utils.h"
|
||||
|
||||
struct wm_backend_t {
|
||||
struct backend_t {
|
||||
xcb_connection_t *conn;
|
||||
xcb_screen_t *screen;
|
||||
int screenp;
|
||||
bool have_xfixes;
|
||||
};
|
||||
|
||||
wm_backend_t *wm_backend_create(const char *display_name) {
|
||||
backend_t *backend_create(const char *display_name) {
|
||||
int screen_num = 0;
|
||||
xcb_connection_t *conn = xcb_connect(display_name, &screen_num);
|
||||
int xcb_conn_error = xcb_connection_has_error(conn);
|
||||
@@ -46,7 +46,7 @@ wm_backend_t *wm_backend_create(const char *display_name) {
|
||||
"SubstructureRedirect)");
|
||||
}
|
||||
|
||||
wm_backend_t *backend = p_new(wm_backend_t, 1);
|
||||
backend_t *backend = p_new(backend_t, 1);
|
||||
backend->conn = conn;
|
||||
backend->screen = screen;
|
||||
backend->screenp = screen_num;
|
||||
@@ -71,7 +71,7 @@ wm_backend_t *wm_backend_create(const char *display_name) {
|
||||
return backend;
|
||||
}
|
||||
|
||||
void wm_backend_destroy(wm_backend_t *backend) {
|
||||
void backend_destroy(backend_t *backend) {
|
||||
if (!backend) return;
|
||||
|
||||
xcb_disconnect(backend->conn);
|
||||
@@ -79,8 +79,8 @@ void wm_backend_destroy(wm_backend_t *backend) {
|
||||
free(backend);
|
||||
}
|
||||
|
||||
static bool detect_monitor_by_randr(const wm_backend_t *backend,
|
||||
wm_output_info_t **outputs, size_t *count) {
|
||||
static bool detect_monitor_by_randr(const backend_t *backend,
|
||||
output_info_t **outputs, size_t *count) {
|
||||
xcb_prefetch_extension_data(backend->conn, &xcb_randr_id);
|
||||
const xcb_query_extension_reply_t *query =
|
||||
xcb_get_extension_data(backend->conn, &xcb_randr_id);
|
||||
@@ -116,11 +116,11 @@ static bool detect_monitor_by_randr(const wm_backend_t *backend,
|
||||
return false;
|
||||
}
|
||||
|
||||
wm_output_info_t *output_list = p_new(wm_output_info_t, len);
|
||||
output_info_t *output_list = p_new(output_info_t, len);
|
||||
xcb_randr_monitor_info_iterator_t iter =
|
||||
xcb_randr_get_monitors_monitors_iterator(monitors_reply);
|
||||
for (int i = 0; iter.rem; xcb_randr_monitor_info_next(&iter), i++) {
|
||||
wm_output_info_t *output = &output_list[i];
|
||||
output_info_t *output = &output_list[i];
|
||||
output->geometry.x = iter.data->x;
|
||||
output->geometry.y = iter.data->y;
|
||||
output->geometry.width = iter.data->width;
|
||||
@@ -152,9 +152,8 @@ static bool detect_monitor_by_randr(const wm_backend_t *backend,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool detect_monitor_by_xinerama(const wm_backend_t *backend,
|
||||
wm_output_info_t **outputs,
|
||||
size_t *count) {
|
||||
static bool detect_monitor_by_xinerama(const backend_t *backend,
|
||||
output_info_t **outputs, size_t *count) {
|
||||
xcb_prefetch_extension_data(backend->conn, &xcb_xinerama_id);
|
||||
const xcb_query_extension_reply_t *query =
|
||||
xcb_get_extension_data(backend->conn, &xcb_xinerama_id);
|
||||
@@ -195,9 +194,9 @@ static bool detect_monitor_by_xinerama(const wm_backend_t *backend,
|
||||
return false;
|
||||
}
|
||||
|
||||
wm_output_info_t *output_list = p_new(wm_output_info_t, len);
|
||||
output_info_t *output_list = p_new(output_info_t, len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
wm_output_info_t *output = &output_list[i];
|
||||
output_info_t *output = &output_list[i];
|
||||
output->geometry.x = screen_info[i].x_org;
|
||||
output->geometry.y = screen_info[i].y_org;
|
||||
output->geometry.width = screen_info[i].width;
|
||||
@@ -216,35 +215,35 @@ static bool detect_monitor_by_xinerama(const wm_backend_t *backend,
|
||||
return true;
|
||||
}
|
||||
|
||||
wm_backend_detect_t *wm_backend_detect(wm_backend_t *backend) {
|
||||
wm_output_info_t *outputs = nullptr;
|
||||
backend_detect_t *backend_detect(backend_t *backend) {
|
||||
output_info_t *outputs = nullptr;
|
||||
size_t count = 0;
|
||||
|
||||
if (detect_monitor_by_randr(backend, &outputs, &count)) {
|
||||
wm_backend_detect_t *detect = output_remove_duplication(outputs, count);
|
||||
backend_detect_t *detect = output_remove_duplication(outputs, count);
|
||||
p_delete(&outputs);
|
||||
return detect;
|
||||
}
|
||||
|
||||
if (detect_monitor_by_xinerama(backend, &outputs, &count)) {
|
||||
wm_backend_detect_t *detect = output_remove_duplication(outputs, count);
|
||||
backend_detect_t *detect = output_remove_duplication(outputs, count);
|
||||
p_delete(&outputs);
|
||||
return detect;
|
||||
}
|
||||
|
||||
wm_output_info_t *output = p_new(wm_output_info_t, 1);
|
||||
output_info_t *output = p_new(output_info_t, 1);
|
||||
output->geometry.x = 0;
|
||||
output->geometry.y = 0;
|
||||
output->geometry.width = backend->screen->width_in_pixels;
|
||||
output->geometry.height = backend->screen->height_in_pixels;
|
||||
|
||||
wm_backend_detect_t *detect = p_new(wm_backend_detect_t, 1);
|
||||
backend_detect_t *detect = p_new(backend_detect_t, 1);
|
||||
detect->outputs = output;
|
||||
detect->output_count = 1;
|
||||
return detect;
|
||||
}
|
||||
|
||||
void wm_backend_detect_destroy(wm_backend_detect_t *detect) {
|
||||
void backend_detect_destroy(backend_detect_t *detect) {
|
||||
if (!detect) return;
|
||||
|
||||
for (size_t i = 0; i < detect->output_count; i++) {
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "core/wm_desc.h"
|
||||
#include "core/types.h"
|
||||
|
||||
typedef struct wm_backend_t wm_backend_t;
|
||||
typedef struct backend_t backend_t;
|
||||
|
||||
typedef struct wm_backend_detect_t {
|
||||
wm_output_info_t *outputs;
|
||||
typedef struct backend_detect_t {
|
||||
output_info_t *outputs;
|
||||
size_t output_count;
|
||||
} wm_backend_detect_t;
|
||||
} backend_detect_t;
|
||||
|
||||
wm_backend_t *wm_backend_create(const char *display_name);
|
||||
void wm_backend_destroy(wm_backend_t *backend);
|
||||
backend_t *backend_create(const char *display_name);
|
||||
void backend_destroy(backend_t *backend);
|
||||
|
||||
wm_backend_detect_t *wm_backend_detect(wm_backend_t *backend);
|
||||
void wm_backend_detect_destroy(wm_backend_detect_t *detect);
|
||||
backend_detect_t *backend_detect(backend_t *backend);
|
||||
void backend_detect_destroy(backend_detect_t *detect);
|
||||
|
||||
255
src/core/event.h
255
src/core/event.h
@@ -2,173 +2,174 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "core/types.h"
|
||||
#include "core/wm_desc.h"
|
||||
|
||||
typedef enum wm_event_type_t {
|
||||
WM_EVENT_KEY_PRESS,
|
||||
WM_EVENT_POINTER_BUTTON_PRESS,
|
||||
WM_EVENT_POINTER_BUTTON_RELEASE,
|
||||
WM_EVENT_POINTER_MOTION,
|
||||
WM_EVENT_POINTER_ENTER,
|
||||
WM_EVENT_WINDOW_MAP_REQUEST,
|
||||
WM_EVENT_WINDOW_REMOVE,
|
||||
WM_EVENT_WINDOW_METADATA_CHANGED,
|
||||
WM_EVENT_WINDOW_HINTS_CHANGED,
|
||||
WM_EVENT_WINDOW_ACTIVATE_REQUEST,
|
||||
WM_EVENT_WINDOW_STATE_REQUEST,
|
||||
WM_EVENT_CONFIGURE_REQUEST,
|
||||
} wm_event_type_t;
|
||||
typedef enum event_type_t {
|
||||
ZDWM_EVENT_KEY_PRESS,
|
||||
ZDWM_EVENT_POINTER_BUTTON_PRESS,
|
||||
ZDWM_EVENT_POINTER_BUTTON_RELEASE,
|
||||
ZDWM_EVENT_POINTER_MOTION,
|
||||
ZDWM_EVENT_POINTER_ENTER,
|
||||
ZDWM_EVENT_WINDOW_MAP_REQUEST,
|
||||
ZDWM_EVENT_WINDOW_REMOVE,
|
||||
ZDWM_EVENT_WINDOW_METADATA_CHANGED,
|
||||
ZDWM_EVENT_WINDOW_HINTS_CHANGED,
|
||||
ZDWM_EVENT_WINDOW_ACTIVATE_REQUEST,
|
||||
ZDWM_EVENT_WINDOW_STATE_REQUEST,
|
||||
ZDWM_EVENT_CONFIGURE_REQUEST,
|
||||
} event_type_t;
|
||||
|
||||
typedef enum wm_modifier_bit_t {
|
||||
WM_MOD_SHIFT = 1u << 0,
|
||||
WM_MOD_CTRL = 1u << 1,
|
||||
WM_MOD_ALT = 1u << 2,
|
||||
WM_MOD_SUPER = 1u << 3,
|
||||
} wm_modifier_bit_t;
|
||||
typedef enum modifier_bit_t {
|
||||
ZDWM_MOD_SHIFT = 1u << 0,
|
||||
ZDWM_MOD_CTRL = 1u << 1,
|
||||
ZDWM_MOD_ALT = 1u << 2,
|
||||
ZDWM_MOD_SUPER = 1u << 3,
|
||||
} modifier_bit_t;
|
||||
|
||||
typedef uint32_t wm_modifier_mask_t;
|
||||
typedef uint32_t wm_keysym_t;
|
||||
typedef uint32_t modifier_mask_t;
|
||||
typedef uint32_t keysym_t;
|
||||
|
||||
typedef struct wm_key_press_event_t {
|
||||
wm_modifier_mask_t modifiers;
|
||||
wm_keysym_t keysym;
|
||||
typedef struct key_press_event_t {
|
||||
modifier_mask_t modifiers;
|
||||
keysym_t keysym;
|
||||
uint32_t keycode;
|
||||
} wm_key_press_event_t;
|
||||
} key_press_event_t;
|
||||
|
||||
typedef enum wm_button_t {
|
||||
WM_BUTTON_LEFT,
|
||||
WM_BUTTON_RIGHT,
|
||||
WM_BUTTON_MIDDLE,
|
||||
} wm_button_t;
|
||||
typedef enum button_t {
|
||||
ZDWM_BUTTON_LEFT,
|
||||
ZDWM_BUTTON_RIGHT,
|
||||
ZDWM_BUTTON_MIDDLE,
|
||||
} button_t;
|
||||
|
||||
typedef struct wm_pointer_button_event_t {
|
||||
wm_modifier_mask_t modifiers;
|
||||
wm_button_t button;
|
||||
wm_window_id_t window;
|
||||
wm_point_t root;
|
||||
wm_point_t local;
|
||||
} wm_pointer_button_event_t;
|
||||
typedef struct pointer_button_event_t {
|
||||
modifier_mask_t modifiers;
|
||||
button_t button;
|
||||
window_id_t window;
|
||||
point_t root;
|
||||
point_t local;
|
||||
} pointer_button_event_t;
|
||||
|
||||
typedef struct wm_pointer_motion_event_t {
|
||||
wm_window_id_t window;
|
||||
wm_point_t root;
|
||||
wm_point_t local;
|
||||
} wm_pointer_motion_event_t;
|
||||
typedef struct pointer_motion_event_t {
|
||||
window_id_t window;
|
||||
point_t root;
|
||||
point_t local;
|
||||
} pointer_motion_event_t;
|
||||
|
||||
typedef struct wm_pointer_enter_event_t {
|
||||
wm_window_id_t window;
|
||||
wm_point_t root;
|
||||
wm_point_t local;
|
||||
} wm_pointer_enter_event_t;
|
||||
typedef struct pointer_enter_event_t {
|
||||
window_id_t window;
|
||||
point_t root;
|
||||
point_t local;
|
||||
} pointer_enter_event_t;
|
||||
|
||||
typedef struct wm_window_map_request_event_t {
|
||||
wm_window_info_t info;
|
||||
wm_window_id_t transient_for;
|
||||
typedef struct window_map_request_event_t {
|
||||
window_info_t info;
|
||||
window_id_t transient_for;
|
||||
bool is_dialog;
|
||||
} wm_window_map_request_event_t;
|
||||
} window_map_request_event_t;
|
||||
|
||||
typedef enum wm_window_remove_reason_t {
|
||||
WM_WINDOW_REMOVE_WITHDRAWN,
|
||||
WM_WINDOW_REMOVE_DESTROY,
|
||||
} wm_window_remove_reason_t;
|
||||
typedef enum window_remove_reason_t {
|
||||
ZDWM_WINDOW_REMOVE_WITHDRAWN,
|
||||
ZDWM_WINDOW_REMOVE_DESTROY,
|
||||
} window_remove_reason_t;
|
||||
|
||||
typedef struct wm_window_remove_event_t {
|
||||
wm_window_id_t window;
|
||||
wm_window_remove_reason_t reason;
|
||||
} wm_window_remove_event_t;
|
||||
typedef struct window_remove_event_t {
|
||||
window_id_t window;
|
||||
window_remove_reason_t reason;
|
||||
} window_remove_event_t;
|
||||
|
||||
typedef enum wm_window_metadata_change_flags_t {
|
||||
WM_WINDOW_METADATA_CHANGE_TITLE = 1u << 0,
|
||||
WM_WINDOW_METADATA_CHANGE_APP_ID = 1u << 1,
|
||||
WM_WINDOW_METADATA_CHANGE_CLASS = 1u << 2,
|
||||
WM_WINDOW_METADATA_CHANGE_INSTANCE = 1u << 3,
|
||||
} wm_window_metadata_change_flags_t;
|
||||
typedef enum window_metadata_change_flags_t {
|
||||
ZDWM_WINDOW_METADATA_CHANGE_TITLE = 1u << 0,
|
||||
ZDWM_WINDOW_METADATA_CHANGE_APP_ID = 1u << 1,
|
||||
ZDWM_WINDOW_METADATA_CHANGE_CLASS = 1u << 2,
|
||||
ZDWM_WINDOW_METADATA_CHANGE_INSTANCE = 1u << 3,
|
||||
} window_metadata_change_flags_t;
|
||||
|
||||
typedef struct wm_window_metadata_change_event_t {
|
||||
wm_window_id_t window;
|
||||
typedef struct window_metadata_change_event_t {
|
||||
window_id_t window;
|
||||
uint32_t changed_fields;
|
||||
const char *title;
|
||||
const char *app_id;
|
||||
const char *class_name;
|
||||
const char *instance_name;
|
||||
} wm_window_metadata_change_event_t;
|
||||
} window_metadata_change_event_t;
|
||||
|
||||
typedef enum wm_window_hint_changed_flags_t {
|
||||
WM_WINDOW_HINT_CHANGED_NONE = 0,
|
||||
WM_WINDOW_HINT_CHANGED_URGENT = 1u << 0,
|
||||
WM_WINDOW_HINT_CHANGED_FIXED_SIZE = 1u << 1,
|
||||
WM_WINDOW_HINT_CHANGED_SKIP_TASKBAR = 1u << 2,
|
||||
} wm_window_hint_changed_flags_t;
|
||||
typedef enum window_hint_changed_flags_t {
|
||||
ZDWM_WINDOW_HINT_CHANGED_NONE = 0,
|
||||
ZDWM_WINDOW_HINT_CHANGED_URGENT = 1u << 0,
|
||||
ZDWM_WINDOW_HINT_CHANGED_FIXED_SIZE = 1u << 1,
|
||||
ZDWM_WINDOW_HINT_CHANGED_SKIP_TASKBAR = 1u << 2,
|
||||
} window_hint_changed_flags_t;
|
||||
|
||||
typedef struct wm_window_hints_changed_event_t {
|
||||
wm_window_id_t window;
|
||||
typedef struct window_hints_changed_event_t {
|
||||
window_id_t window;
|
||||
uint32_t changed_fields;
|
||||
bool urgent;
|
||||
bool fixed_size;
|
||||
bool skip_taskbar;
|
||||
} wm_window_hints_changed_event_t;
|
||||
} window_hints_changed_event_t;
|
||||
|
||||
typedef enum wm_window_activation_source_t {
|
||||
WM_WINDOW_ACTIVATION_SOURCE_LEGACY = 0,
|
||||
WM_WINDOW_ACTIVATION_SOURCE_APPLICATION = 1,
|
||||
WM_WINDOW_ACTIVATION_SOURCE_PAGER = 2,
|
||||
} wm_window_activation_source_t;
|
||||
typedef enum window_activation_source_t {
|
||||
ZDWM_WINDOW_ACTIVATION_SOURCE_LEGACY = 0,
|
||||
ZDWM_WINDOW_ACTIVATION_SOURCE_APPLICATION = 1,
|
||||
ZDWM_WINDOW_ACTIVATION_SOURCE_PAGER = 2,
|
||||
} window_activation_source_t;
|
||||
|
||||
typedef struct wm_window_activate_request_event_t {
|
||||
wm_window_id_t window;
|
||||
wm_window_activation_source_t source;
|
||||
} wm_window_activate_request_event_t;
|
||||
typedef struct window_activate_request_event_t {
|
||||
window_id_t window;
|
||||
window_activation_source_t source;
|
||||
} window_activate_request_event_t;
|
||||
|
||||
typedef enum wm_window_state_request_kind_t {
|
||||
WM_WINDOW_STATE_REQUEST_FULLSCREEN,
|
||||
WM_WINDOW_STATE_REQUEST_MAXIMIZED,
|
||||
WM_WINDOW_STATE_REQUEST_MINIMIZED,
|
||||
} wm_window_state_request_kind_t;
|
||||
typedef enum window_state_request_kind_t {
|
||||
ZDWM_WINDOW_STATE_REQUEST_FULLSCREEN,
|
||||
ZDWM_WINDOW_STATE_REQUEST_MAXIMIZED,
|
||||
ZDWM_WINDOW_STATE_REQUEST_MINIMIZED,
|
||||
} window_state_request_kind_t;
|
||||
|
||||
typedef enum wm_window_state_request_action_t {
|
||||
WM_WINDOW_STATE_REQUEST_ACTION_ADD,
|
||||
WM_WINDOW_STATE_REQUEST_ACTION_REMOVE,
|
||||
WM_WINDOW_STATE_REQUEST_ACTION_TOGGLE,
|
||||
} wm_window_state_request_action_t;
|
||||
typedef enum window_state_request_action_t {
|
||||
ZDWM_WINDOW_STATE_REQUEST_ACTION_ADD,
|
||||
ZDWM_WINDOW_STATE_REQUEST_ACTION_REMOVE,
|
||||
ZDWM_WINDOW_STATE_REQUEST_ACTION_TOGGLE,
|
||||
} window_state_request_action_t;
|
||||
|
||||
typedef struct wm_window_state_request_event_t {
|
||||
wm_window_id_t window;
|
||||
wm_window_state_request_kind_t kind;
|
||||
wm_window_state_request_action_t action;
|
||||
} wm_window_state_request_event_t;
|
||||
typedef struct window_state_request_event_t {
|
||||
window_id_t window;
|
||||
window_state_request_kind_t kind;
|
||||
window_state_request_action_t action;
|
||||
} window_state_request_event_t;
|
||||
|
||||
typedef enum wm_configure_request_field_t {
|
||||
WM_CONFIGURE_REQUEST_FIELD_NONE = 0,
|
||||
WM_CONFIGURE_REQUEST_FIELD_X = 1u << 0,
|
||||
WM_CONFIGURE_REQUEST_FIELD_Y = 1u << 1,
|
||||
WM_CONFIGURE_REQUEST_FIELD_WIDTH = 1u << 2,
|
||||
WM_CONFIGURE_REQUEST_FIELD_HEIGHT = 1u << 3,
|
||||
} wm_configure_request_field_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 wm_configure_request_event_t {
|
||||
wm_window_id_t window;
|
||||
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;
|
||||
} wm_configure_request_event_t;
|
||||
} configure_request_event_t;
|
||||
|
||||
typedef struct wm_event_t {
|
||||
wm_event_type_t type;
|
||||
typedef struct event_t {
|
||||
event_type_t type;
|
||||
uint32_t time_ms;
|
||||
union {
|
||||
wm_key_press_event_t key_press;
|
||||
wm_pointer_button_event_t pointer_button_press;
|
||||
wm_pointer_button_event_t pointer_button_release;
|
||||
wm_pointer_motion_event_t pointer_motion;
|
||||
wm_pointer_enter_event_t pointer_enter;
|
||||
wm_window_map_request_event_t window_map_request;
|
||||
wm_window_remove_event_t window_remove;
|
||||
wm_window_metadata_change_event_t window_metadata_change;
|
||||
wm_window_hints_changed_event_t window_hints_changed;
|
||||
wm_window_activate_request_event_t window_activate_request;
|
||||
wm_window_state_request_event_t window_state_request;
|
||||
wm_configure_request_event_t configure_request;
|
||||
key_press_event_t key_press;
|
||||
pointer_button_event_t pointer_button_press;
|
||||
pointer_button_event_t pointer_button_release;
|
||||
pointer_motion_event_t pointer_motion;
|
||||
pointer_enter_event_t pointer_enter;
|
||||
window_map_request_event_t window_map_request;
|
||||
window_remove_event_t window_remove;
|
||||
window_metadata_change_event_t window_metadata_change;
|
||||
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;
|
||||
} data;
|
||||
} wm_event_t;
|
||||
} event_t;
|
||||
|
||||
@@ -6,23 +6,19 @@
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
void wm_layout_result_init(wm_layout_result_t *result) {
|
||||
void layout_result_init(layout_result_t *result) {
|
||||
result->item_count = 0;
|
||||
result->item_capacity = INIT_CAPACITY;
|
||||
result->items = p_new(wm_layout_item_t, result->item_capacity);
|
||||
result->items = p_new(layout_item_t, result->item_capacity);
|
||||
}
|
||||
|
||||
void wm_layout_result_reset(wm_layout_result_t *result) {
|
||||
result->item_count = 0;
|
||||
}
|
||||
|
||||
void wm_layout_result_cleanup(wm_layout_result_t *result) {
|
||||
void layout_result_cleanup(layout_result_t *result) {
|
||||
p_delete(&result->items);
|
||||
result->item_count = 0;
|
||||
result->item_capacity = 0;
|
||||
}
|
||||
|
||||
void wm_layout_result_push(wm_layout_result_t *result, wm_layout_item_t item) {
|
||||
void layout_result_push(layout_result_t *result, layout_item_t item) {
|
||||
if (result->item_count == result->item_capacity) {
|
||||
size_t new_capacity = next_capacity(result->item_capacity);
|
||||
p_realloc(&result->items, new_capacity);
|
||||
@@ -32,28 +28,27 @@ void wm_layout_result_push(wm_layout_result_t *result, wm_layout_item_t item) {
|
||||
result->items[result->item_count++] = item;
|
||||
}
|
||||
|
||||
void wm_layout_registry_init(wm_layout_registry_t *registry) {
|
||||
void layout_registry_init(layout_registry_t *registry) {
|
||||
registry->slot_count = 0;
|
||||
registry->slot_capacity = INIT_CAPACITY;
|
||||
registry->slots = p_new(wm_layout_slot_t, registry->slot_capacity);
|
||||
registry->slots = p_new(layout_slot_t, registry->slot_capacity);
|
||||
}
|
||||
|
||||
void wm_layout_registry_cleanup(wm_layout_registry_t *registry) {
|
||||
void layout_registry_cleanup(layout_registry_t *registry) {
|
||||
while (registry->slot_count > 0) {
|
||||
wm_layout_slot_t *r = ®istry->slots[--registry->slot_count];
|
||||
layout_slot_t *r = ®istry->slots[--registry->slot_count];
|
||||
p_delete(&r->name);
|
||||
p_delete(&r->symbol);
|
||||
p_delete(&r->description);
|
||||
r->fn = nullptr;
|
||||
r->id = WM_LAYOUT_ID_INVALID;
|
||||
r->id = ZDWM_LAYOUT_ID_INVALID;
|
||||
}
|
||||
p_delete(®istry->slots);
|
||||
registry->slot_count = 0;
|
||||
registry->slot_capacity = 0;
|
||||
}
|
||||
|
||||
bool wm_layout_registry_move(wm_layout_registry_t *src,
|
||||
wm_layout_registry_t *dest) {
|
||||
bool layout_registry_move(layout_registry_t *src, layout_registry_t *dest) {
|
||||
if (!src || !dest) return false;
|
||||
|
||||
dest->slots = src->slots;
|
||||
@@ -67,29 +62,29 @@ bool wm_layout_registry_move(wm_layout_registry_t *src,
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t wm_layout_registry_count(const wm_layout_registry_t *registry) {
|
||||
size_t layout_registry_count(const layout_registry_t *registry) {
|
||||
return registry->slot_count;
|
||||
}
|
||||
|
||||
const wm_layout_slot_t *wm_layout_registry_at(
|
||||
const wm_layout_registry_t *registry, size_t index) {
|
||||
const layout_slot_t *layout_registry_at(const layout_registry_t *registry,
|
||||
size_t index) {
|
||||
if (index >= registry->slot_count) return nullptr;
|
||||
return ®istry->slots[index];
|
||||
}
|
||||
|
||||
wm_layout_id_t wm_layout_register(wm_layout_registry_t *registry,
|
||||
const char *name, const char *symbol,
|
||||
const char *description, wm_layout_fn fn) {
|
||||
if (!name || !symbol) return WM_LAYOUT_ID_INVALID;
|
||||
layout_id_t layout_register(layout_registry_t *registry, const char *name,
|
||||
const char *symbol, const char *description,
|
||||
layout_fn fn) {
|
||||
if (!name || !symbol) return ZDWM_LAYOUT_ID_INVALID;
|
||||
|
||||
if (registry->slot_count == registry->slot_capacity) {
|
||||
size_t new_capacity = next_capacity(registry->slot_capacity);
|
||||
p_realloc(®istry->slots, new_capacity);
|
||||
registry->slot_capacity = new_capacity;
|
||||
}
|
||||
wm_layout_id_t id = (wm_layout_id_t)registry->slot_count;
|
||||
layout_id_t id = (layout_id_t)registry->slot_count;
|
||||
|
||||
wm_layout_slot_t *r = ®istry->slots[registry->slot_count];
|
||||
layout_slot_t *r = ®istry->slots[registry->slot_count];
|
||||
r->id = id;
|
||||
r->name = p_strdup(name);
|
||||
r->symbol = p_strdup(symbol);
|
||||
@@ -100,15 +95,14 @@ wm_layout_id_t wm_layout_register(wm_layout_registry_t *registry,
|
||||
return id;
|
||||
}
|
||||
|
||||
wm_layout_fn wm_layout_get(const wm_layout_registry_t *registry,
|
||||
wm_layout_id_t id) {
|
||||
const wm_layout_slot_t *layout_slot = wm_layout_slot_get(registry, id);
|
||||
layout_fn layout_get(const layout_registry_t *registry, layout_id_t id) {
|
||||
const layout_slot_t *layout_slot = layout_slot_get(registry, id);
|
||||
if (layout_slot) return layout_slot->fn;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const wm_layout_slot_t *wm_layout_slot_get(const wm_layout_registry_t *registry,
|
||||
wm_layout_id_t id) {
|
||||
const layout_slot_t *layout_slot_get(const layout_registry_t *registry,
|
||||
layout_id_t id) {
|
||||
if (id >= registry->slot_count) return nullptr;
|
||||
return ®istry->slots[id];
|
||||
}
|
||||
|
||||
@@ -1,49 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <zdwm/layout.h>
|
||||
|
||||
#include "core/types.h"
|
||||
|
||||
typedef struct wm_layout_ctx_t {
|
||||
wm_output_id_t output_id;
|
||||
wm_workspace_id_t workspace_id;
|
||||
wm_window_id_t focused_window_id;
|
||||
wm_rect_t workarea;
|
||||
/*
|
||||
* 参与本次布局计算的窗口 ID 列表。
|
||||
*
|
||||
* 调用方负责在进入 layout 前完成筛选;这里不包含 floating、sticky、
|
||||
* fullscreen、minimized 等不参与平铺计算的窗口。
|
||||
*
|
||||
* 数组顺序具有语义,layout 应按该顺序解释窗口排列优先级。
|
||||
*/
|
||||
const wm_window_id_t *window_ids;
|
||||
size_t window_count;
|
||||
} wm_layout_ctx_t;
|
||||
typedef zdwm_layout_ctx_t layout_ctx_t;
|
||||
typedef zdwm_layout_item_t layout_item_t;
|
||||
typedef zdwm_layout_result_t layout_result_t;
|
||||
typedef zdwm_layout_fn layout_fn;
|
||||
|
||||
typedef struct wm_layout_item_t {
|
||||
wm_window_id_t window_id;
|
||||
wm_rect_t rect; /* 平铺窗口的目标外框矩形(包含边框) */
|
||||
} wm_layout_item_t;
|
||||
|
||||
typedef struct wm_layout_result_t {
|
||||
wm_layout_item_t *items;
|
||||
size_t item_count;
|
||||
size_t item_capacity;
|
||||
} wm_layout_result_t;
|
||||
|
||||
/*
|
||||
* 返回 true 表示成功生成合法的布局结果。
|
||||
* 返回 false 表示布局计算失败,调用方应丢弃本次结果。
|
||||
*
|
||||
* 该返回值不表示窗口最终几何是否发生变化;
|
||||
* 是否有改动应由调用方在比较当前状态与布局结果后决定。
|
||||
*/
|
||||
typedef bool (*wm_layout_fn)(const wm_layout_ctx_t *ctx,
|
||||
wm_layout_result_t *out);
|
||||
|
||||
typedef struct wm_layout_slot_t {
|
||||
wm_layout_id_t id;
|
||||
typedef struct layout_slot_t {
|
||||
layout_id_t id;
|
||||
/*
|
||||
* 布局名称,用于:
|
||||
* - 配置引用
|
||||
@@ -70,14 +38,14 @@ typedef struct wm_layout_slot_t {
|
||||
*
|
||||
* fn == NULL 表示 floating 布局,即该布局不参与平铺计算。
|
||||
*/
|
||||
wm_layout_fn fn;
|
||||
} wm_layout_slot_t;
|
||||
layout_fn fn;
|
||||
} layout_slot_t;
|
||||
|
||||
typedef struct wm_layout_registry_t {
|
||||
wm_layout_slot_t *slots;
|
||||
typedef struct layout_registry_t {
|
||||
layout_slot_t *slots;
|
||||
size_t slot_count;
|
||||
size_t slot_capacity;
|
||||
} wm_layout_registry_t;
|
||||
} layout_registry_t;
|
||||
|
||||
/*
|
||||
* 调用约束:
|
||||
@@ -85,11 +53,10 @@ typedef struct wm_layout_registry_t {
|
||||
* - 除 init 之外,其余 result 相关接口都要求 result 已初始化
|
||||
* - 传入空指针或未初始化对象属于调用方错误
|
||||
*/
|
||||
void wm_layout_result_init(wm_layout_result_t *result);
|
||||
void wm_layout_result_reset(wm_layout_result_t *result);
|
||||
void wm_layout_result_cleanup(wm_layout_result_t *result);
|
||||
void layout_result_init(layout_result_t *result);
|
||||
void layout_result_cleanup(layout_result_t *result);
|
||||
|
||||
void wm_layout_result_push(wm_layout_result_t *result, wm_layout_item_t item);
|
||||
void layout_result_push(layout_result_t *result, layout_item_t item);
|
||||
|
||||
/*
|
||||
* 调用约束:
|
||||
@@ -97,13 +64,12 @@ void wm_layout_result_push(wm_layout_result_t *result, wm_layout_item_t item);
|
||||
* - 除 init 之外,其余 registry 相关接口都要求 registry 已初始化
|
||||
* - 传入空指针或未初始化对象属于调用方错误
|
||||
*/
|
||||
void wm_layout_registry_init(wm_layout_registry_t *registry);
|
||||
void wm_layout_registry_cleanup(wm_layout_registry_t *registry);
|
||||
bool wm_layout_registry_move(wm_layout_registry_t *src,
|
||||
wm_layout_registry_t *dest);
|
||||
size_t wm_layout_registry_count(const wm_layout_registry_t *registry);
|
||||
const wm_layout_slot_t *wm_layout_registry_at(
|
||||
const wm_layout_registry_t *registry, size_t index);
|
||||
void layout_registry_init(layout_registry_t *registry);
|
||||
void layout_registry_cleanup(layout_registry_t *registry);
|
||||
bool layout_registry_move(layout_registry_t *src, layout_registry_t *dest);
|
||||
size_t layout_registry_count(const layout_registry_t *registry);
|
||||
const layout_slot_t *layout_registry_at(const layout_registry_t *registry,
|
||||
size_t index);
|
||||
|
||||
/*
|
||||
* 注册一个布局并返回其稳定 ID。
|
||||
@@ -119,13 +85,13 @@ const wm_layout_slot_t *wm_layout_registry_at(
|
||||
*
|
||||
* 返回值:
|
||||
* - 成功时返回新注册布局的 ID
|
||||
* - name 或 symbol 非法时返回 WM_LAYOUT_ID_INVALID
|
||||
* - name 或 symbol 非法时返回 ZDWM_LAYOUT_ID_INVALID
|
||||
*
|
||||
* 注册成功后,布局 ID 与其在 registry 中的槽位索引保持一致。
|
||||
*/
|
||||
wm_layout_id_t wm_layout_register(wm_layout_registry_t *registry,
|
||||
const char *name, const char *symbol,
|
||||
const char *description, wm_layout_fn fn);
|
||||
layout_id_t layout_register(layout_registry_t *registry, const char *name,
|
||||
const char *symbol, const char *description,
|
||||
layout_fn fn);
|
||||
/*
|
||||
* 获取可执行的布局函数。
|
||||
*
|
||||
@@ -134,7 +100,6 @@ wm_layout_id_t wm_layout_register(wm_layout_registry_t *registry,
|
||||
* - id 对应的 slot 不存在
|
||||
* - slot 存在,但 fn == NULL(表示 floating 布局)
|
||||
*/
|
||||
wm_layout_fn wm_layout_get(const wm_layout_registry_t *registry,
|
||||
wm_layout_id_t id);
|
||||
const wm_layout_slot_t *wm_layout_slot_get(const wm_layout_registry_t *registry,
|
||||
wm_layout_id_t id);
|
||||
layout_fn layout_get(const layout_registry_t *registry, layout_id_t id);
|
||||
const layout_slot_t *layout_slot_get(const layout_registry_t *registry,
|
||||
layout_id_t id);
|
||||
|
||||
@@ -4,48 +4,99 @@
|
||||
|
||||
#include "core/backend.h"
|
||||
#include "core/state.h"
|
||||
#include "core/types.h"
|
||||
#include "core/wm_desc.h"
|
||||
#include "utils.h"
|
||||
|
||||
bool wm_runtime_init(wm_runtime_t *runtime) {
|
||||
p_clear(runtime, 1);
|
||||
static bool runtime_workspace_desc_has_valid_layouts(
|
||||
const layout_registry_t *layouts, const workspace_desc_t *workspace) {
|
||||
if (!layouts || !workspace) return false;
|
||||
|
||||
wm_backend_t *backend = wm_backend_create(nullptr);
|
||||
if (!backend) return false;
|
||||
|
||||
runtime->backend = backend;
|
||||
|
||||
wm_backend_detect_t *detect = wm_backend_detect(backend);
|
||||
if (!detect || detect->output_count <= 0) {
|
||||
wm_backend_destroy(backend);
|
||||
return false;
|
||||
for (size_t i = 0; i < workspace->layout_count; i++) {
|
||||
if (!layout_slot_get(layouts, workspace->layout_ids[i])) return false;
|
||||
}
|
||||
|
||||
wm_workspace_desc_t *workspaces =
|
||||
p_new(wm_workspace_desc_t, detect->output_count);
|
||||
static wm_layout_id_t ids[] = {0, 1, 2};
|
||||
for (size_t i = 0; i < detect->output_count; i++) {
|
||||
wm_workspace_desc_t *desc = &workspaces[i];
|
||||
desc->output_index = i;
|
||||
desc->name = "web";
|
||||
desc->layout_ids = ids;
|
||||
desc->layout_count = countof(ids);
|
||||
desc->initial_layout_id = 1;
|
||||
}
|
||||
|
||||
wm_state_init(&runtime->state, detect->outputs, detect->output_count,
|
||||
workspaces, detect->output_count);
|
||||
p_delete(&workspaces);
|
||||
wm_backend_detect_destroy(detect);
|
||||
detect = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wm_runtime_shutdown(wm_runtime_t *runtime) {
|
||||
static bool runtime_init_desc_valid(const runtime_init_desc_t *desc) {
|
||||
if (!desc || !desc->backend || !desc->outputs || desc->output_count == 0) {
|
||||
return false;
|
||||
}
|
||||
if (!desc->layouts.slots || desc->layouts.slot_count == 0) return false;
|
||||
if (!desc->workspaces || desc->workspace_count == 0) return false;
|
||||
|
||||
for (size_t i = 0; i < desc->workspace_count; i++) {
|
||||
const workspace_desc_t *workspace = &desc->workspaces[i];
|
||||
if (!workspace_desc_valid(workspace, desc->output_count)) return false;
|
||||
if (!runtime_workspace_desc_has_valid_layouts(&desc->layouts, workspace)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void runtime_workspace_desc_list_cleanup(workspace_desc_t **list,
|
||||
size_t *count) {
|
||||
if (!list || !count) return;
|
||||
|
||||
for (size_t i = 0; i < *count; i++) {
|
||||
workspace_desc_t *workspace = &(*list)[i];
|
||||
p_delete(&workspace->name);
|
||||
p_delete(&workspace->layout_ids);
|
||||
}
|
||||
|
||||
p_delete(list);
|
||||
*count = 0;
|
||||
}
|
||||
|
||||
bool runtime_init(runtime_t *runtime, runtime_init_desc_t *desc) {
|
||||
if (!runtime || !runtime_init_desc_valid(desc)) return false;
|
||||
|
||||
p_clear(runtime, 1);
|
||||
runtime->backend = desc->backend;
|
||||
runtime->layouts = desc->layouts;
|
||||
|
||||
desc->backend = nullptr;
|
||||
p_clear(&desc->layouts, 1);
|
||||
|
||||
state_init(&runtime->state, desc->outputs, desc->output_count,
|
||||
desc->workspaces, desc->workspace_count);
|
||||
|
||||
runtime_workspace_desc_list_cleanup(&desc->workspaces,
|
||||
&desc->workspace_count);
|
||||
desc->outputs = nullptr;
|
||||
desc->output_count = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void runtime_init_desc_cleanup(runtime_init_desc_t *desc) {
|
||||
if (!desc) return;
|
||||
|
||||
if (desc->backend) {
|
||||
backend_destroy(desc->backend);
|
||||
desc->backend = nullptr;
|
||||
}
|
||||
|
||||
if (desc->layouts.slots || desc->layouts.slot_count ||
|
||||
desc->layouts.slot_capacity) {
|
||||
layout_registry_cleanup(&desc->layouts);
|
||||
}
|
||||
|
||||
runtime_workspace_desc_list_cleanup(&desc->workspaces,
|
||||
&desc->workspace_count);
|
||||
desc->outputs = nullptr;
|
||||
desc->output_count = 0;
|
||||
}
|
||||
|
||||
void runtime_shutdown(runtime_t *runtime) {
|
||||
runtime->running = false;
|
||||
wm_state_cleanup(&runtime->state);
|
||||
wm_backend_destroy(runtime->backend);
|
||||
if (runtime->layouts.slots || runtime->layouts.slot_count ||
|
||||
runtime->layouts.slot_capacity) {
|
||||
layout_registry_cleanup(&runtime->layouts);
|
||||
}
|
||||
state_cleanup(&runtime->state);
|
||||
backend_destroy(runtime->backend);
|
||||
runtime->backend = nullptr;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "core/backend.h"
|
||||
#include "core/layout.h"
|
||||
#include "core/state.h"
|
||||
|
||||
typedef struct wm_runtime_t {
|
||||
typedef struct runtime_init_desc_t {
|
||||
backend_t *backend;
|
||||
output_info_t *outputs;
|
||||
size_t output_count;
|
||||
|
||||
layout_registry_t layouts;
|
||||
workspace_desc_t *workspaces;
|
||||
size_t workspace_count;
|
||||
} runtime_init_desc_t;
|
||||
|
||||
typedef struct runtime_t {
|
||||
bool running;
|
||||
bool will_restart;
|
||||
|
||||
wm_state_t state;
|
||||
wm_backend_t *backend;
|
||||
} wm_runtime_t;
|
||||
state_t state;
|
||||
layout_registry_t layouts;
|
||||
backend_t *backend;
|
||||
} runtime_t;
|
||||
|
||||
bool wm_runtime_init(wm_runtime_t *runtime);
|
||||
void wm_runtime_shutdown(wm_runtime_t *runtime);
|
||||
bool runtime_init(runtime_t *runtime, runtime_init_desc_t *desc);
|
||||
void runtime_init_desc_cleanup(runtime_init_desc_t *desc);
|
||||
void runtime_shutdown(runtime_t *runtime);
|
||||
|
||||
296
src/core/state.c
296
src/core/state.c
@@ -7,59 +7,59 @@
|
||||
#include "core/wm_desc.h"
|
||||
#include "utils.h"
|
||||
|
||||
void wm_state_init(wm_state_t *state, const wm_output_info_t *outputs,
|
||||
size_t output_count, const wm_workspace_desc_t *workspaces,
|
||||
size_t workspace_count) {
|
||||
void state_init(state_t *state, const output_info_t *outputs,
|
||||
size_t output_count, const workspace_desc_t *workspaces,
|
||||
size_t workspace_count) {
|
||||
p_clear(state, 1);
|
||||
|
||||
state->outputs = p_new(wm_output_t, output_count);
|
||||
state->outputs = p_new(output_t, output_count);
|
||||
for (size_t i = 0; i < output_count; i++) {
|
||||
const wm_output_info_t *output_info = &outputs[i];
|
||||
wm_output_t *output = &state->outputs[i];
|
||||
const output_info_t *output_info = &outputs[i];
|
||||
output_t *output = &state->outputs[i];
|
||||
|
||||
output->id = (wm_output_id_t)i;
|
||||
output->current_workspace_id = WM_WORKSPACE_ID_INVALID;
|
||||
output->id = (output_id_t)i;
|
||||
output->current_workspace_id = ZDWM_WORKSPACE_ID_INVALID;
|
||||
output->name = p_strdup_nullable(output_info->name);
|
||||
output->geometry = output_info->geometry;
|
||||
output->workarea = output_info->geometry;
|
||||
}
|
||||
state->output_count = output_count;
|
||||
|
||||
state->workspaces = p_new(wm_workspace_t, workspace_count);
|
||||
state->workspaces = p_new(workspace_t, workspace_count);
|
||||
for (size_t i = 0; i < workspace_count; i++) {
|
||||
const wm_workspace_desc_t *workspace_desc = &workspaces[i];
|
||||
if (!wm_workspace_desc_valid(workspace_desc, output_count)) {
|
||||
const workspace_desc_t *workspace_desc = &workspaces[i];
|
||||
if (!workspace_desc_valid(workspace_desc, output_count)) {
|
||||
fatal("workspace desc at index %zu invalid", i);
|
||||
}
|
||||
|
||||
wm_output_t *output = &state->outputs[workspace_desc->output_index];
|
||||
wm_workspace_t *workspace = &state->workspaces[i];
|
||||
workspace->id = (wm_workspace_id_t)i;
|
||||
output_t *output = &state->outputs[workspace_desc->output_index];
|
||||
workspace_t *workspace = &state->workspaces[i];
|
||||
workspace->id = (workspace_id_t)i;
|
||||
workspace->output_id = output->id;
|
||||
workspace->focused_window_id = WM_WINDOW_ID_INVALID;
|
||||
workspace->focused_window_id = ZDWM_WINDOW_ID_INVALID;
|
||||
workspace->available_layouts =
|
||||
p_copy(workspace_desc->layout_ids, workspace_desc->layout_count);
|
||||
workspace->layout_id = workspace_desc->initial_layout_id;
|
||||
workspace->layout_count = workspace_desc->layout_count;
|
||||
workspace->name = p_strdup(workspace_desc->name);
|
||||
|
||||
if (output->current_workspace_id == WM_WORKSPACE_ID_INVALID) {
|
||||
if (output->current_workspace_id == ZDWM_WORKSPACE_ID_INVALID) {
|
||||
output->current_workspace_id = workspace->id;
|
||||
}
|
||||
}
|
||||
state->workspace_count = workspace_count;
|
||||
|
||||
for (size_t i = 0; i < state->output_count; i++) {
|
||||
const wm_output_t *output = &state->outputs[i];
|
||||
if (output->current_workspace_id == WM_WORKSPACE_ID_INVALID) {
|
||||
const output_t *output = &state->outputs[i];
|
||||
if (output->current_workspace_id == ZDWM_WORKSPACE_ID_INVALID) {
|
||||
fatal("output at index %zu has no workspace", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wm_state_cleanup(wm_state_t *state) {
|
||||
void state_cleanup(state_t *state) {
|
||||
for (size_t i = 0; i < state->window_count; i++) {
|
||||
wm_window_t *window = &state->windows[i];
|
||||
window_t *window = &state->windows[i];
|
||||
p_delete(&window->title);
|
||||
p_delete(&window->app_id);
|
||||
p_delete(&window->class_name);
|
||||
@@ -71,7 +71,7 @@ void wm_state_cleanup(wm_state_t *state) {
|
||||
state->window_capacity = 0;
|
||||
|
||||
for (size_t i = 0; i < state->workspace_count; i++) {
|
||||
wm_workspace_t *workspace = &state->workspaces[i];
|
||||
workspace_t *workspace = &state->workspaces[i];
|
||||
p_delete(&workspace->name);
|
||||
p_delete(&workspace->available_layouts);
|
||||
workspace->layout_count = 0;
|
||||
@@ -80,7 +80,7 @@ void wm_state_cleanup(wm_state_t *state) {
|
||||
state->workspace_count = 0;
|
||||
|
||||
for (size_t i = 0; i < state->output_count; i++) {
|
||||
wm_output_t *output = &state->outputs[i];
|
||||
output_t *output = &state->outputs[i];
|
||||
p_delete(&output->name);
|
||||
}
|
||||
p_delete(&state->outputs);
|
||||
@@ -89,44 +89,42 @@ void wm_state_cleanup(wm_state_t *state) {
|
||||
p_clear(state, 1);
|
||||
}
|
||||
|
||||
const wm_workspace_t *wm_state_workspace_get(const wm_state_t *state,
|
||||
wm_workspace_id_t id) {
|
||||
const workspace_t *state_workspace_get(const state_t *state,
|
||||
workspace_id_t id) {
|
||||
if (id < state->workspace_count) return &state->workspaces[id];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const wm_workspace_t *wm_state_workspace_at(const wm_state_t *state,
|
||||
size_t index) {
|
||||
const workspace_t *state_workspace_at(const state_t *state, size_t index) {
|
||||
if (index < state->workspace_count) return &state->workspaces[index];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void wm_state_workspace_adjust_focused_window(
|
||||
const wm_state_t *state, wm_workspace_id_t workspace_id) {
|
||||
wm_workspace_t *workspace =
|
||||
(wm_workspace_t *)wm_state_workspace_get(state, workspace_id);
|
||||
static void state_workspace_adjust_focused_window(const state_t *state,
|
||||
workspace_id_t workspace_id) {
|
||||
workspace_t *workspace =
|
||||
(workspace_t *)state_workspace_get(state, workspace_id);
|
||||
if (!workspace) return;
|
||||
|
||||
const wm_window_t *window =
|
||||
wm_state_window_get(state, workspace->focused_window_id);
|
||||
const window_t *window =
|
||||
state_window_get(state, workspace->focused_window_id);
|
||||
if (window && window->workspace_id == workspace_id) return;
|
||||
|
||||
for (size_t i = state->window_count; i > 0; i--) {
|
||||
wm_window_id_t window_id = state->stack_order[i - 1];
|
||||
const wm_window_t *window = wm_state_window_get(state, window_id);
|
||||
window_id_t window_id = state->stack_order[i - 1];
|
||||
const window_t *window = state_window_get(state, window_id);
|
||||
if (window && window->workspace_id == workspace_id) {
|
||||
workspace->focused_window_id = window_id;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
workspace->focused_window_id = WM_WINDOW_ID_INVALID;
|
||||
workspace->focused_window_id = ZDWM_WINDOW_ID_INVALID;
|
||||
}
|
||||
|
||||
bool wm_state_workspace_cycle_layout(wm_state_t *state,
|
||||
wm_workspace_id_t workspace_id) {
|
||||
wm_workspace_t *workspace =
|
||||
(wm_workspace_t *)wm_state_workspace_get(state, workspace_id);
|
||||
bool state_workspace_cycle_layout(state_t *state, workspace_id_t workspace_id) {
|
||||
workspace_t *workspace =
|
||||
(workspace_t *)state_workspace_get(state, workspace_id);
|
||||
if (!workspace) return false;
|
||||
|
||||
size_t next_index = 0;
|
||||
@@ -146,11 +144,11 @@ bool wm_state_workspace_cycle_layout(wm_state_t *state,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wm_state_workspace_set_layout_by_index(wm_state_t *state,
|
||||
wm_workspace_id_t workspace_id,
|
||||
size_t index) {
|
||||
wm_workspace_t *workspace =
|
||||
(wm_workspace_t *)wm_state_workspace_get(state, workspace_id);
|
||||
bool state_workspace_set_layout_by_index(state_t *state,
|
||||
workspace_id_t workspace_id,
|
||||
size_t index) {
|
||||
workspace_t *workspace =
|
||||
(workspace_t *)state_workspace_get(state, workspace_id);
|
||||
if (!workspace) return false;
|
||||
if (index >= workspace->layout_count) return false;
|
||||
|
||||
@@ -158,11 +156,11 @@ bool wm_state_workspace_set_layout_by_index(wm_state_t *state,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wm_state_workspace_set_layout_by_id(wm_state_t *state,
|
||||
wm_workspace_id_t workspace_id,
|
||||
wm_layout_id_t layout_id) {
|
||||
wm_workspace_t *workspace =
|
||||
(wm_workspace_t *)wm_state_workspace_get(state, workspace_id);
|
||||
bool state_workspace_set_layout_by_id(state_t *state,
|
||||
workspace_id_t workspace_id,
|
||||
layout_id_t layout_id) {
|
||||
workspace_t *workspace =
|
||||
(workspace_t *)state_workspace_get(state, workspace_id);
|
||||
if (!workspace) return false;
|
||||
for (size_t i = 0; i < workspace->layout_count; i++) {
|
||||
if (workspace->available_layouts[i] == layout_id) {
|
||||
@@ -174,29 +172,29 @@ bool wm_state_workspace_set_layout_by_id(wm_state_t *state,
|
||||
return false;
|
||||
}
|
||||
|
||||
void wm_state_workspace_set_focused_window(wm_state_t *state,
|
||||
wm_workspace_id_t workspace_id,
|
||||
wm_window_id_t window_id) {
|
||||
wm_workspace_t *workspace =
|
||||
(wm_workspace_t *)wm_state_workspace_get(state, workspace_id);
|
||||
void state_workspace_set_focused_window(state_t *state,
|
||||
workspace_id_t workspace_id,
|
||||
window_id_t window_id) {
|
||||
workspace_t *workspace =
|
||||
(workspace_t *)state_workspace_get(state, workspace_id);
|
||||
if (!workspace) return;
|
||||
|
||||
for (size_t i = 0; i < state->window_count; i++) {
|
||||
wm_window_t *window = &state->windows[i];
|
||||
window_t *window = &state->windows[i];
|
||||
if (window->id == window_id && window->workspace_id == workspace_id) {
|
||||
workspace->focused_window_id = window_id;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wm_state_workspace_adjust_focused_window(state, workspace_id);
|
||||
state_workspace_adjust_focused_window(state, workspace_id);
|
||||
}
|
||||
|
||||
size_t wm_state_workspace_count(const wm_state_t *state) {
|
||||
size_t state_workspace_count(const state_t *state) {
|
||||
return state->workspace_count;
|
||||
}
|
||||
|
||||
bool wm_state_workspace_valid(const wm_state_t *state, wm_workspace_id_t id) {
|
||||
bool state_workspace_valid(const state_t *state, workspace_id_t id) {
|
||||
return id < state->workspace_count;
|
||||
|
||||
/* 线性扫描作为备用 */
|
||||
@@ -211,39 +209,35 @@ bool wm_state_workspace_valid(const wm_state_t *state, wm_workspace_id_t id) {
|
||||
#endif
|
||||
}
|
||||
|
||||
const wm_output_t *wm_state_output_get(const wm_state_t *state,
|
||||
wm_output_id_t id) {
|
||||
const output_t *state_output_get(const state_t *state, output_id_t id) {
|
||||
if (id < state->output_count) return &state->outputs[id];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const wm_output_t *wm_state_output_at(const wm_state_t *state, size_t index) {
|
||||
const output_t *state_output_at(const state_t *state, size_t index) {
|
||||
if (index < state->output_count) return &state->outputs[index];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void wm_state_output_set_workarea(wm_state_t *state, wm_output_id_t output_id,
|
||||
wm_rect_t workarea) {
|
||||
wm_output_t *output = (wm_output_t *)wm_state_output_get(state, output_id);
|
||||
void state_output_set_workarea(state_t *state, output_id_t output_id,
|
||||
rect_t workarea) {
|
||||
output_t *output = (output_t *)state_output_get(state, output_id);
|
||||
if (output) output->workarea = workarea;
|
||||
}
|
||||
|
||||
void wm_state_output_set_current_workspace(wm_state_t *state,
|
||||
wm_output_id_t output_id,
|
||||
wm_workspace_id_t workspace_id) {
|
||||
wm_output_t *output = (wm_output_t *)wm_state_output_get(state, output_id);
|
||||
void state_output_set_current_workspace(state_t *state, output_id_t output_id,
|
||||
workspace_id_t workspace_id) {
|
||||
output_t *output = (output_t *)state_output_get(state, output_id);
|
||||
if (!output) return;
|
||||
const wm_workspace_t *workspace = wm_state_workspace_get(state, workspace_id);
|
||||
const workspace_t *workspace = state_workspace_get(state, workspace_id);
|
||||
if (!workspace || workspace->output_id != output_id) return;
|
||||
|
||||
output->current_workspace_id = workspace_id;
|
||||
}
|
||||
|
||||
size_t wm_state_output_count(const wm_state_t *state) {
|
||||
return state->output_count;
|
||||
}
|
||||
size_t state_output_count(const state_t *state) { return state->output_count; }
|
||||
|
||||
bool wm_state_output_valid(const wm_state_t *state, wm_output_id_t id) {
|
||||
bool state_output_valid(const state_t *state, output_id_t id) {
|
||||
return id < state->output_count;
|
||||
|
||||
/* 线性扫描作为备用 */
|
||||
@@ -258,10 +252,9 @@ bool wm_state_output_valid(const wm_state_t *state, wm_output_id_t id) {
|
||||
#endif
|
||||
}
|
||||
|
||||
const wm_window_t *wm_state_window_add(wm_state_t *state,
|
||||
const wm_window_info_t *info) {
|
||||
wm_window_id_t id = info->id;
|
||||
wm_window_t *window = (wm_window_t *)wm_state_window_get(state, id);
|
||||
const window_t *state_window_add(state_t *state, const window_info_t *info) {
|
||||
window_id_t id = info->id;
|
||||
window_t *window = (window_t *)state_window_get(state, id);
|
||||
if (!window) {
|
||||
if (state->window_count == state->window_capacity) {
|
||||
size_t capacity = next_capacity(state->window_capacity);
|
||||
@@ -272,27 +265,26 @@ const wm_window_t *wm_state_window_add(wm_state_t *state,
|
||||
window = &state->windows[state->window_count];
|
||||
p_clear(window, 1);
|
||||
window->id = id;
|
||||
window->workspace_id = WM_WORKSPACE_ID_INVALID;
|
||||
window->workspace_id = ZDWM_WORKSPACE_ID_INVALID;
|
||||
|
||||
state->stack_order[state->window_count] = id;
|
||||
state->window_count++;
|
||||
}
|
||||
|
||||
wm_state_window_set_geometry_mode(state, id, info->geometry_mode);
|
||||
wm_state_window_set_urgent(state, id, info->urgent);
|
||||
wm_state_window_set_fixed_size(state, id, info->fixed_size);
|
||||
wm_state_window_set_frame_rect(state, id, info->frame_rect);
|
||||
wm_state_window_set_title(state, id, info->title);
|
||||
wm_state_window_set_app_id(state, id, info->app_id);
|
||||
wm_state_window_set_class(state, id, info->class_name);
|
||||
wm_state_window_set_instance(state, id, info->instance_name);
|
||||
wm_state_window_set_skip_taskbar(state, id, info->skip_taskbar);
|
||||
state_window_set_geometry_mode(state, id, info->geometry_mode);
|
||||
state_window_set_urgent(state, id, info->urgent);
|
||||
state_window_set_fixed_size(state, id, info->fixed_size);
|
||||
state_window_set_frame_rect(state, id, info->frame_rect);
|
||||
state_window_set_title(state, id, info->title);
|
||||
state_window_set_app_id(state, id, info->app_id);
|
||||
state_window_set_class(state, id, info->class_name);
|
||||
state_window_set_instance(state, id, info->instance_name);
|
||||
state_window_set_skip_taskbar(state, id, info->skip_taskbar);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
const wm_window_t *wm_state_window_get(const wm_state_t *state,
|
||||
wm_window_id_t id) {
|
||||
const window_t *state_window_get(const state_t *state, window_id_t id) {
|
||||
for (size_t i = 0; i < state->window_count; i++) {
|
||||
if (state->windows[i].id == id) return &state->windows[i];
|
||||
}
|
||||
@@ -300,13 +292,13 @@ const wm_window_t *wm_state_window_get(const wm_state_t *state,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const wm_window_t *wm_state_window_at(const wm_state_t *state, size_t index) {
|
||||
const window_t *state_window_at(const state_t *state, size_t index) {
|
||||
if (index < state->window_count) return &state->windows[index];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void wm_state_window_remove(wm_state_t *state, wm_window_id_t id) {
|
||||
void state_window_remove(state_t *state, window_id_t id) {
|
||||
bool matched = false;
|
||||
size_t index = 0;
|
||||
for (size_t i = 0; i < state->window_count; i++) {
|
||||
@@ -318,8 +310,8 @@ void wm_state_window_remove(wm_state_t *state, wm_window_id_t id) {
|
||||
}
|
||||
if (!matched) return;
|
||||
|
||||
wm_window_t *window = &state->windows[index];
|
||||
wm_workspace_id_t workspace_id = window->workspace_id;
|
||||
window_t *window = &state->windows[index];
|
||||
workspace_id_t workspace_id = window->workspace_id;
|
||||
p_delete(&window->title);
|
||||
p_delete(&window->app_id);
|
||||
p_delete(&window->class_name);
|
||||
@@ -330,8 +322,8 @@ void wm_state_window_remove(wm_state_t *state, wm_window_id_t id) {
|
||||
}
|
||||
window = &state->windows[state->window_count - 1];
|
||||
p_clear(window, 1);
|
||||
window->id = WM_WINDOW_ID_INVALID;
|
||||
window->workspace_id = WM_WORKSPACE_ID_INVALID;
|
||||
window->id = ZDWM_WINDOW_ID_INVALID;
|
||||
window->workspace_id = ZDWM_WORKSPACE_ID_INVALID;
|
||||
|
||||
matched = false;
|
||||
for (size_t i = 0; i < state->window_count; i++) {
|
||||
@@ -345,109 +337,105 @@ void wm_state_window_remove(wm_state_t *state, wm_window_id_t id) {
|
||||
for (size_t i = index + 1; i < state->window_count; i++) {
|
||||
state->stack_order[i - 1] = state->stack_order[i];
|
||||
}
|
||||
state->stack_order[state->window_count - 1] = WM_WINDOW_ID_INVALID;
|
||||
state->stack_order[state->window_count - 1] = ZDWM_WINDOW_ID_INVALID;
|
||||
}
|
||||
|
||||
state->window_count--;
|
||||
|
||||
wm_workspace_t *workspace =
|
||||
(wm_workspace_t *)wm_state_workspace_get(state, workspace_id);
|
||||
workspace_t *workspace =
|
||||
(workspace_t *)state_workspace_get(state, workspace_id);
|
||||
if (workspace && workspace->focused_window_id == id) {
|
||||
wm_state_workspace_adjust_focused_window(state, workspace_id);
|
||||
state_workspace_adjust_focused_window(state, workspace_id);
|
||||
}
|
||||
}
|
||||
|
||||
size_t wm_state_window_count(const wm_state_t *state) {
|
||||
return state->window_count;
|
||||
}
|
||||
size_t state_window_count(const state_t *state) { return state->window_count; }
|
||||
|
||||
void wm_state_window_set_workspace(wm_state_t *state, wm_window_id_t window_id,
|
||||
wm_workspace_id_t workspace_id) {
|
||||
const wm_workspace_t *workspace = wm_state_workspace_get(state, workspace_id);
|
||||
wm_window_t *window = (wm_window_t *)wm_state_window_get(state, window_id);
|
||||
void state_window_set_workspace(state_t *state, window_id_t window_id,
|
||||
workspace_id_t workspace_id) {
|
||||
const workspace_t *workspace = state_workspace_get(state, workspace_id);
|
||||
window_t *window = (window_t *)state_window_get(state, window_id);
|
||||
if (!workspace || !window || window->workspace_id == workspace_id) return;
|
||||
|
||||
workspace = wm_state_workspace_get(state, window->workspace_id);
|
||||
workspace = state_workspace_get(state, window->workspace_id);
|
||||
window->workspace_id = workspace_id;
|
||||
|
||||
if (workspace && workspace->focused_window_id == window_id) {
|
||||
wm_state_workspace_adjust_focused_window(state, workspace->id);
|
||||
state_workspace_adjust_focused_window(state, workspace->id);
|
||||
}
|
||||
|
||||
wm_state_workspace_adjust_focused_window(state, workspace_id);
|
||||
state_workspace_adjust_focused_window(state, workspace_id);
|
||||
}
|
||||
|
||||
void wm_state_window_set_geometry_mode(
|
||||
wm_state_t *state, wm_window_id_t window_id,
|
||||
wm_window_geometry_mode_t geometry_mode) {
|
||||
wm_window_t *window = (wm_window_t *)wm_state_window_get(state, window_id);
|
||||
void state_window_set_geometry_mode(state_t *state, window_id_t window_id,
|
||||
window_geometry_mode_t geometry_mode) {
|
||||
window_t *window = (window_t *)state_window_get(state, window_id);
|
||||
if (!window) return;
|
||||
|
||||
window->geometry_mode = geometry_mode;
|
||||
}
|
||||
|
||||
void wm_state_window_set_floating(wm_state_t *state, wm_window_id_t window_id,
|
||||
bool floating) {
|
||||
wm_window_t *window = (wm_window_t *)wm_state_window_get(state, window_id);
|
||||
void state_window_set_floating(state_t *state, window_id_t window_id,
|
||||
bool floating) {
|
||||
window_t *window = (window_t *)state_window_get(state, window_id);
|
||||
if (!window) return;
|
||||
|
||||
window->floating = floating;
|
||||
}
|
||||
|
||||
void wm_state_window_set_sticky(wm_state_t *state, wm_window_id_t window_id,
|
||||
bool sticky) {
|
||||
wm_window_t *window = (wm_window_t *)wm_state_window_get(state, window_id);
|
||||
void state_window_set_sticky(state_t *state, window_id_t window_id,
|
||||
bool sticky) {
|
||||
window_t *window = (window_t *)state_window_get(state, window_id);
|
||||
if (!window) return;
|
||||
|
||||
window->sticky = sticky;
|
||||
if (window->sticky) wm_state_window_set_floating(state, window_id, true);
|
||||
if (window->sticky) state_window_set_floating(state, window_id, true);
|
||||
}
|
||||
|
||||
void wm_state_window_set_urgent(wm_state_t *state, wm_window_id_t window_id,
|
||||
bool urgent) {
|
||||
wm_window_t *window = (wm_window_t *)wm_state_window_get(state, window_id);
|
||||
void state_window_set_urgent(state_t *state, window_id_t window_id,
|
||||
bool urgent) {
|
||||
window_t *window = (window_t *)state_window_get(state, window_id);
|
||||
if (!window) return;
|
||||
|
||||
window->urgent = urgent;
|
||||
}
|
||||
|
||||
void wm_state_window_set_fixed_size(wm_state_t *state, wm_window_id_t window_id,
|
||||
bool fixed_size) {
|
||||
wm_window_t *window = (wm_window_t *)wm_state_window_get(state, window_id);
|
||||
void state_window_set_fixed_size(state_t *state, window_id_t window_id,
|
||||
bool fixed_size) {
|
||||
window_t *window = (window_t *)state_window_get(state, window_id);
|
||||
if (!window) return;
|
||||
|
||||
window->fixed_size = fixed_size;
|
||||
if (fixed_size) wm_state_window_set_floating(state, window_id, true);
|
||||
if (fixed_size) state_window_set_floating(state, window_id, true);
|
||||
}
|
||||
|
||||
void wm_state_window_set_skip_taskbar(wm_state_t *state,
|
||||
wm_window_id_t window_id,
|
||||
bool skip_taskbar) {
|
||||
wm_window_t *window = (wm_window_t *)wm_state_window_get(state, window_id);
|
||||
void state_window_set_skip_taskbar(state_t *state, window_id_t window_id,
|
||||
bool skip_taskbar) {
|
||||
window_t *window = (window_t *)state_window_get(state, window_id);
|
||||
if (!window) return;
|
||||
|
||||
window->skip_taskbar = skip_taskbar;
|
||||
}
|
||||
|
||||
void wm_state_window_set_float_rect(wm_state_t *state, wm_window_id_t window_id,
|
||||
wm_rect_t float_rect) {
|
||||
wm_window_t *window = (wm_window_t *)wm_state_window_get(state, window_id);
|
||||
void state_window_set_float_rect(state_t *state, window_id_t window_id,
|
||||
rect_t float_rect) {
|
||||
window_t *window = (window_t *)state_window_get(state, window_id);
|
||||
if (!window) return;
|
||||
|
||||
window->float_rect = float_rect;
|
||||
}
|
||||
|
||||
void wm_state_window_set_frame_rect(wm_state_t *state, wm_window_id_t window_id,
|
||||
wm_rect_t frame_rect) {
|
||||
wm_window_t *window = (wm_window_t *)wm_state_window_get(state, window_id);
|
||||
void state_window_set_frame_rect(state_t *state, window_id_t window_id,
|
||||
rect_t frame_rect) {
|
||||
window_t *window = (window_t *)state_window_get(state, window_id);
|
||||
if (!window) return;
|
||||
|
||||
window->frame_rect = frame_rect;
|
||||
}
|
||||
|
||||
bool wm_state_window_set_title(wm_state_t *state, wm_window_id_t window_id,
|
||||
const char *title) {
|
||||
wm_window_t *window = (wm_window_t *)wm_state_window_get(state, window_id);
|
||||
bool state_window_set_title(state_t *state, window_id_t window_id,
|
||||
const char *title) {
|
||||
window_t *window = (window_t *)state_window_get(state, window_id);
|
||||
if (!window) return false;
|
||||
|
||||
p_delete(&window->title);
|
||||
@@ -456,9 +444,9 @@ bool wm_state_window_set_title(wm_state_t *state, wm_window_id_t window_id,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wm_state_window_set_app_id(wm_state_t *state, wm_window_id_t window_id,
|
||||
const char *app_id) {
|
||||
wm_window_t *window = (wm_window_t *)wm_state_window_get(state, window_id);
|
||||
bool state_window_set_app_id(state_t *state, window_id_t window_id,
|
||||
const char *app_id) {
|
||||
window_t *window = (window_t *)state_window_get(state, window_id);
|
||||
if (!window) return false;
|
||||
|
||||
p_delete(&window->app_id);
|
||||
@@ -466,9 +454,9 @@ bool wm_state_window_set_app_id(wm_state_t *state, wm_window_id_t window_id,
|
||||
|
||||
return true;
|
||||
}
|
||||
bool wm_state_window_set_class(wm_state_t *state, wm_window_id_t window_id,
|
||||
const char *class_name) {
|
||||
wm_window_t *window = (wm_window_t *)wm_state_window_get(state, window_id);
|
||||
bool state_window_set_class(state_t *state, window_id_t window_id,
|
||||
const char *class_name) {
|
||||
window_t *window = (window_t *)state_window_get(state, window_id);
|
||||
if (!window) return false;
|
||||
|
||||
p_delete(&window->class_name);
|
||||
@@ -476,9 +464,9 @@ bool wm_state_window_set_class(wm_state_t *state, wm_window_id_t window_id,
|
||||
|
||||
return true;
|
||||
}
|
||||
bool wm_state_window_set_instance(wm_state_t *state, wm_window_id_t window_id,
|
||||
const char *instance_name) {
|
||||
wm_window_t *window = (wm_window_t *)wm_state_window_get(state, window_id);
|
||||
bool state_window_set_instance(state_t *state, window_id_t window_id,
|
||||
const char *instance_name) {
|
||||
window_t *window = (window_t *)state_window_get(state, window_id);
|
||||
if (!window) return false;
|
||||
|
||||
p_delete(&window->instance_name);
|
||||
@@ -487,16 +475,16 @@ bool wm_state_window_set_instance(wm_state_t *state, wm_window_id_t window_id,
|
||||
return true;
|
||||
}
|
||||
|
||||
const wm_window_id_t *wm_state_stack_order(const wm_state_t *state) {
|
||||
const window_id_t *state_stack_order(const state_t *state) {
|
||||
return state->stack_order;
|
||||
}
|
||||
|
||||
wm_window_id_t wm_state_stack_at(const wm_state_t *state, size_t index) {
|
||||
if (index >= state->window_count) return WM_WINDOW_ID_INVALID;
|
||||
window_id_t state_stack_at(const state_t *state, size_t index) {
|
||||
if (index >= state->window_count) return ZDWM_WINDOW_ID_INVALID;
|
||||
return state->stack_order[index];
|
||||
}
|
||||
|
||||
bool wm_state_stack_raise(wm_state_t *state, wm_window_id_t window_id) {
|
||||
bool state_stack_raise(state_t *state, window_id_t window_id) {
|
||||
bool matched = false;
|
||||
size_t index = 0;
|
||||
for (size_t i = 0; i < state->window_count; i++) {
|
||||
@@ -517,7 +505,7 @@ bool wm_state_stack_raise(wm_state_t *state, wm_window_id_t window_id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wm_state_stack_lower(wm_state_t *state, wm_window_id_t window_id) {
|
||||
bool state_stack_lower(state_t *state, window_id_t window_id) {
|
||||
bool matched = false;
|
||||
size_t index = 0;
|
||||
for (size_t i = 0; i < state->window_count; i++) {
|
||||
|
||||
181
src/core/state.h
181
src/core/state.h
@@ -6,19 +6,19 @@
|
||||
#include "core/wm_desc.h"
|
||||
|
||||
/* 核心实体定义 */
|
||||
typedef struct wm_window_t {
|
||||
wm_window_id_t id;
|
||||
wm_workspace_id_t workspace_id;
|
||||
typedef struct window_t {
|
||||
window_id_t id;
|
||||
workspace_id_t workspace_id;
|
||||
|
||||
wm_window_geometry_mode_t geometry_mode;
|
||||
window_geometry_mode_t geometry_mode;
|
||||
bool floating;
|
||||
bool sticky;
|
||||
bool urgent;
|
||||
bool fixed_size;
|
||||
|
||||
/* 几何信息(均为包含边框后的外框矩形) */
|
||||
wm_rect_t float_rect; /* floating 模式下记忆的外框矩形 */
|
||||
wm_rect_t frame_rect; /* 当前外框矩形(由 layout 或 float_rect 解析) */
|
||||
rect_t float_rect; /* floating 模式下记忆的外框矩形 */
|
||||
rect_t frame_rect; /* 当前外框矩形(由 layout 或 float_rect 解析) */
|
||||
|
||||
/* 元数据(核心算法不依赖,仅用于规则匹配和信息展示) */
|
||||
const char *title;
|
||||
@@ -27,67 +27,67 @@ typedef struct wm_window_t {
|
||||
const char *instance_name;
|
||||
|
||||
bool skip_taskbar;
|
||||
} wm_window_t;
|
||||
} window_t;
|
||||
|
||||
typedef struct wm_workspace_t {
|
||||
wm_workspace_id_t id;
|
||||
wm_output_id_t output_id; /* 固定归属某个输出 */
|
||||
wm_layout_id_t layout_id; /* 当前活动布局(可用布局列表中的一个) */
|
||||
wm_window_id_t focused_window_id;
|
||||
typedef struct workspace_t {
|
||||
workspace_id_t id;
|
||||
output_id_t output_id; /* 固定归属某个输出 */
|
||||
layout_id_t layout_id; /* 当前活动布局(可用布局列表中的一个) */
|
||||
window_id_t focused_window_id;
|
||||
|
||||
/* 当前 workspace 的可用布局列表 */
|
||||
const wm_layout_id_t *available_layouts;
|
||||
const layout_id_t *available_layouts;
|
||||
size_t layout_count;
|
||||
|
||||
/* 名称(核心算法不依赖) */
|
||||
const char *name;
|
||||
} wm_workspace_t;
|
||||
} workspace_t;
|
||||
|
||||
typedef struct wm_output_t {
|
||||
wm_output_id_t id;
|
||||
wm_workspace_id_t current_workspace_id;
|
||||
typedef struct output_t {
|
||||
output_id_t id;
|
||||
workspace_id_t current_workspace_id;
|
||||
const char *name;
|
||||
wm_rect_t geometry; /* 输出完整几何 */
|
||||
wm_rect_t workarea; /* 可用区域(排除面板等) */
|
||||
} wm_output_t;
|
||||
rect_t geometry; /* 输出完整几何 */
|
||||
rect_t workarea; /* 可用区域(排除面板等) */
|
||||
} output_t;
|
||||
|
||||
/* 全局状态容器 */
|
||||
typedef struct wm_state_t {
|
||||
typedef struct state_t {
|
||||
/* 按 id 稳定引用的 workspace / output 集合 */
|
||||
wm_workspace_t *workspaces;
|
||||
workspace_t *workspaces;
|
||||
size_t workspace_count;
|
||||
|
||||
wm_output_t *outputs;
|
||||
output_t *outputs;
|
||||
size_t output_count;
|
||||
|
||||
wm_window_t *windows;
|
||||
window_t *windows;
|
||||
size_t window_count;
|
||||
size_t window_capacity;
|
||||
|
||||
/* 与 windows[] 一一对应的堆叠顺序视图,长度等于 window_count */
|
||||
wm_window_id_t *stack_order;
|
||||
window_id_t *stack_order;
|
||||
|
||||
} wm_state_t;
|
||||
} state_t;
|
||||
|
||||
/*
|
||||
* 调用约束:
|
||||
* - state 必须是有效的非空指针
|
||||
* - wm_state_init() / wm_state_cleanup() 必须成对调用
|
||||
* - 同一个 state 生命周期内,wm_state_init() 不允许重复调用
|
||||
* - 除 wm_state_init() 外,其余 state 相关接口都要求 state 已初始化
|
||||
* - workspaces[i] 必须满足 wm_workspace_desc_valid(&workspaces[i],
|
||||
* - state_init() / state_cleanup() 必须成对调用
|
||||
* - 同一个 state 生命周期内,state_init() 不允许重复调用
|
||||
* - 除 state_init() 外,其余 state 相关接口都要求 state 已初始化
|
||||
* - workspaces[i] 必须满足 workspace_desc_valid(&workspaces[i],
|
||||
* output_count)
|
||||
* - 传入空指针、未初始化对象或违反前置条件属于调用方错误
|
||||
*
|
||||
* 初始化时根据描述表构建 outputs[] 与 workspaces[]。
|
||||
* workspace_id 由 state 按描述表顺序分配并保持稳定,不从 desc 中读取。
|
||||
* 每个 output 的 current_workspace_id 会自动设置为首个归属到该 output 的
|
||||
* workspace;若某个 output 没有任何归属 workspace,wm_state_init() 会失败。
|
||||
* workspace;若某个 output 没有任何归属 workspace,state_init() 会失败。
|
||||
*/
|
||||
void wm_state_init(wm_state_t *state, const wm_output_info_t *outputs,
|
||||
size_t output_count, const wm_workspace_desc_t *workspaces,
|
||||
void state_init(state_t *state, const output_info_t *outputs,
|
||||
size_t output_count, const workspace_desc_t *workspaces,
|
||||
size_t workspace_count);
|
||||
void wm_state_cleanup(wm_state_t *state);
|
||||
void state_cleanup(state_t *state);
|
||||
|
||||
/*
|
||||
* state 持有的 workspace 集合接口
|
||||
@@ -95,23 +95,22 @@ void wm_state_cleanup(wm_state_t *state);
|
||||
* 这组接口对外只提供只读访问。
|
||||
* workspace 的运行期可变状态必须通过专门的 state 级更新接口修改。
|
||||
*/
|
||||
const wm_workspace_t *wm_state_workspace_get(const wm_state_t *state,
|
||||
wm_workspace_id_t id);
|
||||
const wm_workspace_t *wm_state_workspace_at(const wm_state_t *state,
|
||||
const workspace_t *state_workspace_get(const state_t *state,
|
||||
workspace_id_t id);
|
||||
const workspace_t *state_workspace_at(const state_t *state, size_t index);
|
||||
bool state_workspace_cycle_layout(state_t *state,
|
||||
workspace_id_t workspace_id);
|
||||
bool state_workspace_set_layout_by_index(state_t *state,
|
||||
workspace_id_t workspace_id,
|
||||
size_t index);
|
||||
bool wm_state_workspace_cycle_layout(wm_state_t *state,
|
||||
wm_workspace_id_t workspace_id);
|
||||
bool wm_state_workspace_set_layout_by_index(wm_state_t *state,
|
||||
wm_workspace_id_t workspace_id,
|
||||
size_t index);
|
||||
bool wm_state_workspace_set_layout_by_id(wm_state_t *state,
|
||||
wm_workspace_id_t workspace_id,
|
||||
wm_layout_id_t layout_id);
|
||||
void wm_state_workspace_set_focused_window(wm_state_t *state,
|
||||
wm_workspace_id_t workspace_id,
|
||||
wm_window_id_t window_id);
|
||||
size_t wm_state_workspace_count(const wm_state_t *state);
|
||||
bool wm_state_workspace_valid(const wm_state_t *state, wm_workspace_id_t id);
|
||||
bool state_workspace_set_layout_by_id(state_t *state,
|
||||
workspace_id_t workspace_id,
|
||||
layout_id_t layout_id);
|
||||
void state_workspace_set_focused_window(state_t *state,
|
||||
workspace_id_t workspace_id,
|
||||
window_id_t window_id);
|
||||
size_t state_workspace_count(const state_t *state);
|
||||
bool state_workspace_valid(const state_t *state, workspace_id_t id);
|
||||
|
||||
/*
|
||||
* state 持有的 output 集合接口
|
||||
@@ -119,21 +118,20 @@ bool wm_state_workspace_valid(const wm_state_t *state, wm_workspace_id_t id);
|
||||
* 这组接口对外只提供只读访问。
|
||||
* output 的运行期可变状态必须通过专门的 state 级更新接口修改。
|
||||
*/
|
||||
const wm_output_t *wm_state_output_get(const wm_state_t *state,
|
||||
wm_output_id_t id);
|
||||
const wm_output_t *wm_state_output_at(const wm_state_t *state, size_t index);
|
||||
void wm_state_output_set_workarea(wm_state_t *state, wm_output_id_t output_id,
|
||||
wm_rect_t workarea);
|
||||
void wm_state_output_set_current_workspace(wm_state_t *state,
|
||||
wm_output_id_t output_id,
|
||||
wm_workspace_id_t workspace_id);
|
||||
size_t wm_state_output_count(const wm_state_t *state);
|
||||
bool wm_state_output_valid(const wm_state_t *state, wm_output_id_t id);
|
||||
const output_t *state_output_get(const state_t *state, output_id_t id);
|
||||
const output_t *state_output_at(const state_t *state, size_t index);
|
||||
void state_output_set_workarea(state_t *state, output_id_t output_id,
|
||||
rect_t workarea);
|
||||
void state_output_set_current_workspace(state_t *state,
|
||||
output_id_t output_id,
|
||||
workspace_id_t workspace_id);
|
||||
size_t state_output_count(const state_t *state);
|
||||
bool state_output_valid(const state_t *state, output_id_t id);
|
||||
|
||||
/*
|
||||
* state 持有的 window 集合接口
|
||||
*
|
||||
* 这组接口负责管理 wm_state_t.windows[] 容器本身,并保持
|
||||
* 这组接口负责管理 state_t.windows[] 容器本身,并保持
|
||||
* stack_order[] 与 windows[] 同步。
|
||||
* 对外只提供只读访问。
|
||||
* window 的运行期可变状态必须通过专门的 state 级更新接口修改。
|
||||
@@ -142,54 +140,51 @@ bool wm_state_output_valid(const wm_state_t *state, wm_output_id_t id);
|
||||
* 添加窗口,并将其追加到 stack_order[] 顶部。
|
||||
*
|
||||
* info 提供 backend 已探测到的窗口基础信息。
|
||||
* workspace 归属与其他策略相关字段由后续 wm_state_window_* 接口设置。
|
||||
* workspace 归属与其他策略相关字段由后续 state_window_* 接口设置。
|
||||
*/
|
||||
const wm_window_t *wm_state_window_add(wm_state_t *state,
|
||||
const wm_window_info_t *info);
|
||||
const wm_window_t *wm_state_window_get(const wm_state_t *state,
|
||||
wm_window_id_t id);
|
||||
const wm_window_t *wm_state_window_at(const wm_state_t *state, size_t index);
|
||||
const window_t *state_window_add(state_t *state,
|
||||
const window_info_t *info);
|
||||
const window_t *state_window_get(const state_t *state, window_id_t id);
|
||||
const window_t *state_window_at(const state_t *state, size_t index);
|
||||
/* 删除窗口,并同步从 stack_order[] 中移除。 */
|
||||
void wm_state_window_remove(wm_state_t *state, wm_window_id_t id);
|
||||
size_t wm_state_window_count(const wm_state_t *state);
|
||||
void state_window_remove(state_t *state, window_id_t id);
|
||||
size_t state_window_count(const state_t *state);
|
||||
|
||||
/* state 持有的单个 window 状态更新接口 */
|
||||
void wm_state_window_set_workspace(wm_state_t *state, wm_window_id_t window_id,
|
||||
wm_workspace_id_t workspace_id);
|
||||
void wm_state_window_set_geometry_mode(wm_state_t *state,
|
||||
wm_window_id_t window_id,
|
||||
wm_window_geometry_mode_t geometry_mode);
|
||||
void wm_state_window_set_floating(wm_state_t *state, wm_window_id_t window_id,
|
||||
void state_window_set_workspace(state_t *state, window_id_t window_id,
|
||||
workspace_id_t workspace_id);
|
||||
void state_window_set_geometry_mode(state_t *state, window_id_t window_id,
|
||||
window_geometry_mode_t geometry_mode);
|
||||
void state_window_set_floating(state_t *state, window_id_t window_id,
|
||||
bool floating);
|
||||
void wm_state_window_set_sticky(wm_state_t *state, wm_window_id_t window_id,
|
||||
void state_window_set_sticky(state_t *state, window_id_t window_id,
|
||||
bool sticky);
|
||||
void wm_state_window_set_urgent(wm_state_t *state, wm_window_id_t window_id,
|
||||
void state_window_set_urgent(state_t *state, window_id_t window_id,
|
||||
bool urgent);
|
||||
void wm_state_window_set_fixed_size(wm_state_t *state, wm_window_id_t window_id,
|
||||
void state_window_set_fixed_size(state_t *state, window_id_t window_id,
|
||||
bool fixed_size);
|
||||
void wm_state_window_set_skip_taskbar(wm_state_t *state,
|
||||
wm_window_id_t window_id,
|
||||
void state_window_set_skip_taskbar(state_t *state, window_id_t window_id,
|
||||
bool skip_taskbar);
|
||||
void wm_state_window_set_float_rect(wm_state_t *state, wm_window_id_t window_id,
|
||||
wm_rect_t float_rect);
|
||||
void wm_state_window_set_frame_rect(wm_state_t *state, wm_window_id_t window_id,
|
||||
wm_rect_t frame_rect);
|
||||
bool wm_state_window_set_title(wm_state_t *state, wm_window_id_t window_id,
|
||||
void state_window_set_float_rect(state_t *state, window_id_t window_id,
|
||||
rect_t float_rect);
|
||||
void state_window_set_frame_rect(state_t *state, window_id_t window_id,
|
||||
rect_t frame_rect);
|
||||
bool state_window_set_title(state_t *state, window_id_t window_id,
|
||||
const char *title);
|
||||
bool wm_state_window_set_app_id(wm_state_t *state, wm_window_id_t window_id,
|
||||
bool state_window_set_app_id(state_t *state, window_id_t window_id,
|
||||
const char *app_id);
|
||||
bool wm_state_window_set_class(wm_state_t *state, wm_window_id_t window_id,
|
||||
bool state_window_set_class(state_t *state, window_id_t window_id,
|
||||
const char *class_name);
|
||||
bool wm_state_window_set_instance(wm_state_t *state, wm_window_id_t window_id,
|
||||
bool state_window_set_instance(state_t *state, window_id_t window_id,
|
||||
const char *instance_name);
|
||||
|
||||
/*
|
||||
* state 持有的堆叠顺序接口
|
||||
*
|
||||
* stack_order[] 是全局 z-order 的唯一真相,从下到上排列。
|
||||
* 其长度恒等于 wm_state_window_count(state),因此不提供单独的 count 接口。
|
||||
* 其长度恒等于 state_window_count(state),因此不提供单独的 count 接口。
|
||||
*/
|
||||
const wm_window_id_t *wm_state_stack_order(const wm_state_t *state);
|
||||
wm_window_id_t wm_state_stack_at(const wm_state_t *state, size_t index);
|
||||
bool wm_state_stack_raise(wm_state_t *state, wm_window_id_t window_id);
|
||||
bool wm_state_stack_lower(wm_state_t *state, wm_window_id_t window_id);
|
||||
const window_id_t *state_stack_order(const state_t *state);
|
||||
window_id_t state_stack_at(const state_t *state, size_t index);
|
||||
bool state_stack_raise(state_t *state, window_id_t window_id);
|
||||
bool state_stack_lower(state_t *state, window_id_t window_id);
|
||||
|
||||
@@ -1,45 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint32_t wm_window_id_t;
|
||||
typedef uint32_t wm_workspace_id_t;
|
||||
typedef uint32_t wm_output_id_t;
|
||||
typedef uint32_t wm_layout_id_t;
|
||||
#include <zdwm/types.h>
|
||||
|
||||
/* clang-format off */
|
||||
/* 无效 ID 标记 */
|
||||
#define WM_WINDOW_ID_INVALID ((wm_window_id_t)0)
|
||||
#define WM_WORKSPACE_ID_INVALID ((wm_workspace_id_t)UINT32_MAX)
|
||||
#define WM_OUTPUT_ID_INVALID ((wm_output_id_t)UINT32_MAX)
|
||||
#define WM_LAYOUT_ID_INVALID ((wm_layout_id_t)UINT32_MAX)
|
||||
typedef zdwm_layout_id_t layout_id_t;
|
||||
typedef zdwm_window_id_t window_id_t;
|
||||
typedef zdwm_workspace_id_t workspace_id_t;
|
||||
typedef uint32_t output_id_t;
|
||||
|
||||
typedef zdwm_rect_t rect_t;
|
||||
typedef zdwm_output_info_t output_info_t;
|
||||
/* clang-format on */
|
||||
|
||||
typedef struct wm_point_t {
|
||||
#define ZDWM_OUTPUT_ID_INVALID ((output_id_t)UINT32_MAX)
|
||||
|
||||
typedef struct point_t {
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
} wm_point_t;
|
||||
} point_t;
|
||||
|
||||
typedef struct wm_rect_t {
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
} wm_rect_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 wm_window_geometry_mode_t {
|
||||
WM_GEOMETRY_NORMAL,
|
||||
WM_GEOMETRY_MAXIMIZED,
|
||||
WM_GEOMETRY_FULLSCREEN,
|
||||
WM_GEOMETRY_MINIMIZED,
|
||||
} wm_window_geometry_mode_t;
|
||||
typedef enum focus_direction_t {
|
||||
ZDWM_FOCUS_PREV,
|
||||
ZDWM_FOCUS_NEXT,
|
||||
} focus_direction_t;
|
||||
|
||||
typedef enum wm_focus_direction_t {
|
||||
WM_FOCUS_PREV,
|
||||
WM_FOCUS_NEXT,
|
||||
} wm_focus_direction_t;
|
||||
|
||||
typedef enum wm_cross_output_policy_t {
|
||||
WM_CROSS_OUTPUT_KEEP_WORKSPACE,
|
||||
WM_CROSS_OUTPUT_MOVE_TO_TARGET_WORKSPACE,
|
||||
} wm_cross_output_policy_t;
|
||||
typedef enum cross_output_policy_t {
|
||||
ZDWM_CROSS_OUTPUT_KEEP_WORKSPACE,
|
||||
ZDWM_CROSS_OUTPUT_MOVE_TO_TARGET_WORKSPACE,
|
||||
} cross_output_policy_t;
|
||||
|
||||
@@ -4,46 +4,41 @@
|
||||
|
||||
#include "core/types.h"
|
||||
|
||||
typedef struct wm_output_info_t {
|
||||
char *name;
|
||||
wm_rect_t geometry;
|
||||
} wm_output_info_t;
|
||||
|
||||
/*
|
||||
* 由 backend 提供的窗口基础信息。
|
||||
*
|
||||
* 这些字符串由调用方提供;state 如需长期持有,应自行复制。
|
||||
*/
|
||||
typedef struct wm_window_info_t {
|
||||
wm_window_id_t id;
|
||||
wm_rect_t frame_rect;
|
||||
typedef struct window_info_t {
|
||||
window_id_t id;
|
||||
rect_t frame_rect;
|
||||
|
||||
const char *title;
|
||||
const char *app_id;
|
||||
const char *class_name;
|
||||
const char *instance_name;
|
||||
|
||||
wm_window_geometry_mode_t geometry_mode;
|
||||
window_geometry_mode_t geometry_mode;
|
||||
bool urgent;
|
||||
bool fixed_size;
|
||||
bool skip_taskbar;
|
||||
} wm_window_info_t;
|
||||
} window_info_t;
|
||||
|
||||
typedef struct wm_workspace_desc_t {
|
||||
size_t output_index; /* 对应 wm_state_init() 中 outputs[] 的索引 */
|
||||
typedef struct workspace_desc_t {
|
||||
size_t output_index; /* 对应 state_init() 中 outputs[] 的索引 */
|
||||
const char *name;
|
||||
const wm_layout_id_t *layout_ids;
|
||||
const layout_id_t *layout_ids;
|
||||
size_t layout_count;
|
||||
wm_layout_id_t initial_layout_id;
|
||||
} wm_workspace_desc_t;
|
||||
layout_id_t initial_layout_id;
|
||||
} workspace_desc_t;
|
||||
|
||||
/*
|
||||
* workspace 描述校验接口。
|
||||
*
|
||||
* 这组接口只校验描述表自身的一致性,不访问 state。
|
||||
*/
|
||||
static inline bool wm_workspace_desc_layouts_valid(
|
||||
const wm_workspace_desc_t *workspace) {
|
||||
static inline bool workspace_desc_layouts_valid(
|
||||
const workspace_desc_t *workspace) {
|
||||
if (!workspace || !workspace->layout_count || !workspace->layout_ids) {
|
||||
return false;
|
||||
}
|
||||
@@ -55,10 +50,10 @@ static inline bool wm_workspace_desc_layouts_valid(
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool wm_workspace_desc_valid(const wm_workspace_desc_t *workspace,
|
||||
static inline bool workspace_desc_valid(const workspace_desc_t *workspace,
|
||||
size_t output_count) {
|
||||
if (!workspace || !workspace->name) return false;
|
||||
if (workspace->output_index >= output_count) return false;
|
||||
|
||||
return wm_workspace_desc_layouts_valid(workspace);
|
||||
return workspace_desc_layouts_valid(workspace);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@ add_executable(${OUTPUT_UTILS_TEST_APP_NAME}
|
||||
${SOURCE_DIR}/backend/output_utils.c
|
||||
)
|
||||
|
||||
target_include_directories(${OUTPUT_UTILS_TEST_APP_NAME} SYSTEM
|
||||
PRIVATE ${INCLUDE_DIR}
|
||||
)
|
||||
|
||||
target_include_directories(${OUTPUT_UTILS_TEST_APP_NAME}
|
||||
PRIVATE ${SOURCE_DIR}
|
||||
PRIVATE ${BUILD_DIR}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#include "backend/output_utils.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "backend/output_utils.h"
|
||||
#include "core/types.h"
|
||||
#include "utils.h"
|
||||
|
||||
static void assert_output_geometry(const wm_output_info_t *output, int32_t x,
|
||||
int32_t y, int32_t width,
|
||||
int32_t height) {
|
||||
static void assert_output_geometry(const output_info_t *output, int32_t x,
|
||||
int32_t y, int32_t width, int32_t height) {
|
||||
assert(output);
|
||||
assert(output->geometry.x == x);
|
||||
assert(output->geometry.y == y);
|
||||
@@ -14,7 +15,7 @@ static void assert_output_geometry(const wm_output_info_t *output, int32_t x,
|
||||
assert(output->geometry.height == height);
|
||||
}
|
||||
|
||||
static void destroy_detect_result(wm_backend_detect_t *detect) {
|
||||
static void destroy_detect_result(backend_detect_t *detect) {
|
||||
assert(detect);
|
||||
for (size_t i = 0; i < detect->output_count; i++) {
|
||||
p_delete(&detect->outputs[i].name);
|
||||
@@ -24,14 +25,14 @@ static void destroy_detect_result(wm_backend_detect_t *detect) {
|
||||
}
|
||||
|
||||
static void test_output_remove_duplication_invalid_input(void) {
|
||||
wm_output_info_t output = {0};
|
||||
output_info_t output = {0};
|
||||
|
||||
assert(output_remove_duplication(nullptr, 0) == nullptr);
|
||||
assert(output_remove_duplication(&output, 0) == nullptr);
|
||||
}
|
||||
|
||||
static void test_output_remove_duplication_keeps_non_nested_outputs(void) {
|
||||
wm_output_info_t outputs[] = {
|
||||
output_info_t outputs[] = {
|
||||
{
|
||||
.geometry = {.x = 0, .y = 0, .width = 3840, .height = 1080},
|
||||
},
|
||||
@@ -46,7 +47,7 @@ static void test_output_remove_duplication_keeps_non_nested_outputs(void) {
|
||||
},
|
||||
};
|
||||
|
||||
wm_backend_detect_t *detect =
|
||||
backend_detect_t *detect =
|
||||
output_remove_duplication(outputs, countof(outputs));
|
||||
assert(detect);
|
||||
assert(detect->output_count == 2);
|
||||
|
||||
@@ -12,6 +12,7 @@ add_executable(${TEST_APP_NAME}
|
||||
|
||||
target_include_directories(${TEST_APP_NAME} SYSTEM
|
||||
PRIVATE ${deps_INCLUDE_DIRS}
|
||||
PRIVATE ${INCLUDE_DIR}
|
||||
)
|
||||
target_include_directories(${TEST_APP_NAME}
|
||||
PRIVATE ${SOURCE_DIR}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "core/runtime.h"
|
||||
|
||||
int main(void) {
|
||||
wm_runtime_t runtime = {0};
|
||||
wm_runtime_init(&runtime);
|
||||
runtime_t runtime = {0};
|
||||
runtime_init(&runtime, nullptr);
|
||||
|
||||
wm_runtime_shutdown(&runtime);
|
||||
runtime_shutdown(&runtime);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user