Compare commits
9 Commits
b14be7b8dd
...
9275d14c5f
| Author | SHA1 | Date | |
|---|---|---|---|
|
9275d14c5f
|
|||
|
c1a4795a85
|
|||
|
8fcf46979a
|
|||
|
56f8380028
|
|||
|
2c3c264ddd
|
|||
|
3031adf3cb
|
|||
|
1b6a4788be
|
|||
|
474ed8dc69
|
|||
|
964de33b23
|
@@ -22,8 +22,10 @@
|
|||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
#include "base/memory.h"
|
#include "base/memory.h"
|
||||||
#include "base/window_list.h"
|
#include "base/window_list.h"
|
||||||
|
#include "core/event.h"
|
||||||
#include "core/plan.h"
|
#include "core/plan.h"
|
||||||
#include "core/types.h"
|
#include "core/types.h"
|
||||||
|
#include "core/window.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
typedef struct atom_item_t {
|
typedef struct atom_item_t {
|
||||||
@@ -625,3 +627,54 @@ bool backend_apply_effect(
|
|||||||
xcb_flush(backend->conn);
|
xcb_flush(backend->conn);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backend_scan_result_t *backend_scan_windows(backend_t *backend) {
|
||||||
|
auto conn = backend->conn;
|
||||||
|
auto root = backend->screen->root;
|
||||||
|
auto cookie = xcb_query_tree_unchecked(conn, root);
|
||||||
|
auto reply = xcb_query_tree_reply(conn, cookie, nullptr);
|
||||||
|
if (!reply) return nullptr;
|
||||||
|
|
||||||
|
auto length = xcb_query_tree_children_length(reply);
|
||||||
|
if (!length) {
|
||||||
|
p_delete(&reply);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto list = xcb_query_tree_children(reply);
|
||||||
|
|
||||||
|
backend_scan_result_t *result = p_new(backend_scan_result_t, 1);
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
auto slot = (window_map_request_event_t *)
|
||||||
|
array_push(result->windows, result->count, result->capacity);
|
||||||
|
if (!populate_window_event(backend, list[i], slot)) {
|
||||||
|
window_layer_props_cleanup(&slot->props);
|
||||||
|
window_metadata_cleanup(&slot->metadata);
|
||||||
|
result->count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p_delete(&reply);
|
||||||
|
|
||||||
|
if (result->count == 0) {
|
||||||
|
backend_scan_result_destroy(result);
|
||||||
|
result = nullptr;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void backend_scan_result_destroy(backend_scan_result_t *result) {
|
||||||
|
if (!result) return;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < result->count; i++) {
|
||||||
|
window_map_request_event_t *ev = &result->windows[i];
|
||||||
|
window_layer_props_cleanup(&ev->props);
|
||||||
|
window_metadata_cleanup(&ev->metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
p_delete(&result->windows);
|
||||||
|
p_delete(&result);
|
||||||
|
}
|
||||||
|
|||||||
@@ -91,18 +91,13 @@ static bool urgent_from_states(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool handle_map_request(
|
bool populate_window_event(
|
||||||
backend_t *backend,
|
backend_t *backend,
|
||||||
event_t *event,
|
xcb_window_t window,
|
||||||
const xcb_map_request_event_t *xcb_event
|
window_map_request_event_t *ev
|
||||||
) {
|
) {
|
||||||
xcb_window_t window = xcb_event->window;
|
ev->window = (window_id_t)window;
|
||||||
|
ev->transient_for = window_get_transient_for(backend, window);
|
||||||
event->type = ZDWM_EVENT_WINDOW_MAP_REQUEST;
|
|
||||||
|
|
||||||
window_map_request_event_t *ev = &event->as.window_map_request;
|
|
||||||
ev->window = (window_id_t)window;
|
|
||||||
ev->transient_for = window_get_transient_for(backend, window);
|
|
||||||
|
|
||||||
xcb_get_window_attributes_reply_t *wa =
|
xcb_get_window_attributes_reply_t *wa =
|
||||||
window_get_attributes(backend, window);
|
window_get_attributes(backend, window);
|
||||||
@@ -167,6 +162,19 @@ static bool handle_map_request(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool handle_map_request(
|
||||||
|
backend_t *backend,
|
||||||
|
event_t *event,
|
||||||
|
const xcb_map_request_event_t *xcb_event
|
||||||
|
) {
|
||||||
|
event->type = ZDWM_EVENT_WINDOW_MAP_REQUEST;
|
||||||
|
return populate_window_event(
|
||||||
|
backend,
|
||||||
|
xcb_event->window,
|
||||||
|
&event->as.window_map_request
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static bool handle_unmap_notify(
|
static bool handle_unmap_notify(
|
||||||
backend_t *backend,
|
backend_t *backend,
|
||||||
event_t *event,
|
event_t *event,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
|
|
||||||
#include "base/window_list.h"
|
#include "base/window_list.h"
|
||||||
|
#include "core/event.h"
|
||||||
|
|
||||||
#define ATOM_LIST(X) \
|
#define ATOM_LIST(X) \
|
||||||
X(COMPOUND_TEXT) \
|
X(COMPOUND_TEXT) \
|
||||||
@@ -94,3 +95,9 @@ struct backend_t {
|
|||||||
window_list_t map;
|
window_list_t map;
|
||||||
window_list_t kill;
|
window_list_t kill;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool populate_window_event(
|
||||||
|
struct backend_t *backend,
|
||||||
|
xcb_window_t window,
|
||||||
|
window_map_request_event_t *ev
|
||||||
|
);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include <zdwm/action.h>
|
#include <zdwm/action.h>
|
||||||
#include <zdwm/types.h>
|
#include <zdwm/types.h>
|
||||||
|
|
||||||
#include "base/log.h"
|
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
|
|
||||||
static constexpr char launcher[] =
|
static constexpr char launcher[] =
|
||||||
@@ -32,7 +31,6 @@ static void quit(
|
|||||||
const zdwm_action_api_t *api,
|
const zdwm_action_api_t *api,
|
||||||
const zdwm_action_arg_t *arg
|
const zdwm_action_arg_t *arg
|
||||||
) {
|
) {
|
||||||
logger("quit: restart: %s\n", arg->b ? "true" : "false");
|
|
||||||
api->quit(runtime, arg->b);
|
api->quit(runtime, arg->b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,6 +43,30 @@ static void raise_or_run(
|
|||||||
api->raise_or_run(runtime, args->class_name, args->command);
|
api->raise_or_run(runtime, args->class_name, args->command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void toggle_fullscreen(
|
||||||
|
zdwm_runtime_t *runtime,
|
||||||
|
const zdwm_action_api_t *api,
|
||||||
|
const zdwm_action_arg_t *arg
|
||||||
|
) {
|
||||||
|
api->toggle_fullscreen(runtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void toggle_maximize(
|
||||||
|
zdwm_runtime_t *runtime,
|
||||||
|
const zdwm_action_api_t *api,
|
||||||
|
const zdwm_action_arg_t *arg
|
||||||
|
) {
|
||||||
|
api->toggle_maximize(runtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void toggle_floating(
|
||||||
|
zdwm_runtime_t *runtime,
|
||||||
|
const zdwm_action_api_t *api,
|
||||||
|
const zdwm_action_arg_t *arg
|
||||||
|
) {
|
||||||
|
api->toggle_floating(runtime);
|
||||||
|
}
|
||||||
|
|
||||||
bool config_defaults_build(
|
bool config_defaults_build(
|
||||||
const zdwm_api_t *api,
|
const zdwm_api_t *api,
|
||||||
zdwm_config_builder_t *builder,
|
zdwm_config_builder_t *builder,
|
||||||
@@ -118,6 +140,9 @@ bool config_defaults_build(
|
|||||||
BIND(default_mode, Super "+e", raise_or_run, {.ptr = &editor});
|
BIND(default_mode, Super "+e", raise_or_run, {.ptr = &editor});
|
||||||
BIND(default_mode, Super "+q", raise_or_run, {.ptr = &browser});
|
BIND(default_mode, Super "+q", raise_or_run, {.ptr = &browser});
|
||||||
BIND(default_mode, Super "+a", raise_or_run, {.ptr = &chrome});
|
BIND(default_mode, Super "+a", raise_or_run, {.ptr = &chrome});
|
||||||
|
BIND(default_mode, Super "+f", toggle_fullscreen, {0});
|
||||||
|
BIND(default_mode, Super "+m", toggle_maximize, {0});
|
||||||
|
BIND(default_mode, Super "+Control+space", toggle_floating, {0});
|
||||||
|
|
||||||
#undef BIND
|
#undef BIND
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -10,6 +11,7 @@
|
|||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
#include "core/command.h"
|
#include "core/command.h"
|
||||||
#include "core/command_buffer.h"
|
#include "core/command_buffer.h"
|
||||||
|
#include "core/runtime.h"
|
||||||
#include "core/state.h"
|
#include "core/state.h"
|
||||||
#include "core/types.h"
|
#include "core/types.h"
|
||||||
#include "core/window.h"
|
#include "core/window.h"
|
||||||
@@ -66,7 +68,7 @@ get_next_window_by_class(state_t *state, const char *class_name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void raise_or_run(
|
void raise_or_run(
|
||||||
zdwm_runtime_t *runtime,
|
runtime_t *runtime,
|
||||||
const char *class_name,
|
const char *class_name,
|
||||||
const char *command
|
const char *command
|
||||||
) {
|
) {
|
||||||
@@ -88,3 +90,90 @@ void raise_or_run(
|
|||||||
};
|
};
|
||||||
command_buffer_push(&runtime->command_buffer, &focus_cmd);
|
command_buffer_push(&runtime->command_buffer, &focus_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const window_t *get_current_focused_window(const state_t *state) {
|
||||||
|
auto output = state_output_at(state, state->current_output_index);
|
||||||
|
auto workspace = state_workspace_get(state, output->current_workspace_id);
|
||||||
|
return state_window_get(state, workspace->focused_window_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggle_fullscreen(runtime_t *runtime) {
|
||||||
|
auto window = get_current_focused_window(&runtime->state);
|
||||||
|
if (!window) return;
|
||||||
|
|
||||||
|
command_t window_set_fullscreen_cmd = {
|
||||||
|
.type = ZDWM_COMMAND_WINDOW_SET_FULLSCREEN,
|
||||||
|
.as.fullscreen = {
|
||||||
|
.window = window->id,
|
||||||
|
.state = !window->fullscreen,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
command_buffer_push(&runtime->command_buffer, &window_set_fullscreen_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggle_maximize(runtime_t *runtime) {
|
||||||
|
auto window = get_current_focused_window(&runtime->state);
|
||||||
|
if (!window) return;
|
||||||
|
|
||||||
|
command_t window_set_maximized_cmd = {
|
||||||
|
.type = ZDWM_COMMAND_WINDOW_SET_MAXIMIZED,
|
||||||
|
.as.maximized = {
|
||||||
|
.window = window->id,
|
||||||
|
.state = !window->maximized,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
command_buffer_push(&runtime->command_buffer, &window_set_maximized_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggle_floating(runtime_t *runtime) {
|
||||||
|
auto window = get_current_focused_window(&runtime->state);
|
||||||
|
if (!window) return;
|
||||||
|
|
||||||
|
command_t window_set_floating_cmd = {
|
||||||
|
.type = ZDWM_COMMAND_WINDOW_SET_FLOATING,
|
||||||
|
.as.floating = {
|
||||||
|
.window = window->id,
|
||||||
|
.state = !window->floating,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
command_buffer_push(&runtime->command_buffer, &window_set_floating_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void toggle_sticky(runtime_t *runtime) {
|
||||||
|
auto window = get_current_focused_window(&runtime->state);
|
||||||
|
if (!window) return;
|
||||||
|
|
||||||
|
command_t window_set_sticky_cmd = {
|
||||||
|
.type = ZDWM_COMMAND_WINDOW_SET_STICKY,
|
||||||
|
.as.sticky = {
|
||||||
|
.window = window->id,
|
||||||
|
.state = !window->sticky,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
command_buffer_push(&runtime->command_buffer, &window_set_sticky_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void switch_workspace(runtime_t *runtime, workspace_id_t workspace_id) {
|
||||||
|
auto workspace = state_workspace_get(&runtime->state, workspace_id);
|
||||||
|
if (!workspace) return;
|
||||||
|
|
||||||
|
command_t switch_workspace_cmd = {
|
||||||
|
.type = ZDWM_COMMAND_SWITCH_WORKSPACE,
|
||||||
|
.as.switch_workspace.workspace = workspace_id
|
||||||
|
};
|
||||||
|
command_buffer_push(&runtime->command_buffer, &switch_workspace_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cycle_layout(runtime_t *runtime, int32_t delta) {
|
||||||
|
auto state = &runtime->state;
|
||||||
|
auto output = state_output_at(state, state->current_output_index);
|
||||||
|
auto workspace = state_workspace_get(state, output->current_workspace_id);
|
||||||
|
if (!state_workspace_cycle_layout(state, workspace->id, delta)) return;
|
||||||
|
|
||||||
|
runtime->plan.need_relayout = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cycle_current_output(runtime_t *runtime, int32_t delta) {
|
||||||
|
auto state = &runtime->state;
|
||||||
|
state_cycle_current_output(state, delta);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/runtime.h"
|
#include <stdint.h>
|
||||||
|
#include <zdwm/action.h>
|
||||||
|
|
||||||
void spawn(const char *command);
|
void spawn(const char *command);
|
||||||
void quit(runtime_t *runtime, bool restart);
|
void quit(zdwm_runtime_t *runtime, bool restart);
|
||||||
void raise_or_run(
|
void raise_or_run(
|
||||||
zdwm_runtime_t *runtime,
|
zdwm_runtime_t *runtime,
|
||||||
const char *class_name,
|
const char *class_name,
|
||||||
const char *command
|
const char *command
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void toggle_fullscreen(zdwm_runtime_t *runtime);
|
||||||
|
void toggle_maximize(zdwm_runtime_t *runtime);
|
||||||
|
void toggle_floating(zdwm_runtime_t *runtime);
|
||||||
|
void toggle_sticky(zdwm_runtime_t *runtime);
|
||||||
|
void switch_workspace(
|
||||||
|
zdwm_runtime_t *runtime,
|
||||||
|
zdwm_workspace_id_t workspace_id
|
||||||
|
);
|
||||||
|
void cycle_layout(zdwm_runtime_t *runtime, int32_t delta);
|
||||||
|
void cycle_current_output(zdwm_runtime_t *runtime, int32_t delta);
|
||||||
|
|||||||
@@ -37,3 +37,17 @@ bool backend_apply_effect(
|
|||||||
const effect_t *effects,
|
const effect_t *effects,
|
||||||
size_t effect_count
|
size_t effect_count
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typedef struct backend_scan_result_t {
|
||||||
|
window_map_request_event_t *windows;
|
||||||
|
size_t count;
|
||||||
|
size_t capacity;
|
||||||
|
} backend_scan_result_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 扫描已有窗口
|
||||||
|
*
|
||||||
|
* @details 仅扫描窗口并获取其基础信息
|
||||||
|
*/
|
||||||
|
backend_scan_result_t *backend_scan_windows(backend_t *backend);
|
||||||
|
void backend_scan_result_destroy(backend_scan_result_t *result);
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ static void route_map_request(
|
|||||||
const window_map_request_event_t *e,
|
const window_map_request_event_t *e,
|
||||||
command_buffer_t *out
|
command_buffer_t *out
|
||||||
) {
|
) {
|
||||||
|
if (e->override_redirect) return;
|
||||||
if (state_window_get(state, e->window)) return;
|
if (state_window_get(state, e->window)) return;
|
||||||
|
|
||||||
window_layer_type_t layer_type = window_classify_layer(&e->props);
|
window_layer_type_t layer_type = window_classify_layer(&e->props);
|
||||||
@@ -140,6 +141,90 @@ static void route_window_remove(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void route_window_metadata_changed(
|
||||||
|
state_t *state,
|
||||||
|
const window_metadata_change_event_t *e
|
||||||
|
) {
|
||||||
|
auto window = state_window_get(state, e->window);
|
||||||
|
if (!window) return;
|
||||||
|
|
||||||
|
auto window_id = e->window;
|
||||||
|
auto metadata = &e->metadata;
|
||||||
|
|
||||||
|
if (e->changed_fields & ZDWM_WINDOW_METADATA_CHANGE_TITLE) {
|
||||||
|
state_window_set_title(state, window_id, metadata->title);
|
||||||
|
}
|
||||||
|
if (e->changed_fields & ZDWM_WINDOW_METADATA_CHANGE_APP_ID) {
|
||||||
|
state_window_set_app_id(state, window_id, metadata->app_id);
|
||||||
|
}
|
||||||
|
if (e->changed_fields & ZDWM_WINDOW_METADATA_CHANGE_ROLE) {
|
||||||
|
state_window_set_role(state, window_id, metadata->role);
|
||||||
|
}
|
||||||
|
if (e->changed_fields & ZDWM_WINDOW_METADATA_CHANGE_CLASS) {
|
||||||
|
state_window_set_class(state, window_id, metadata->class_name);
|
||||||
|
}
|
||||||
|
if (e->changed_fields & ZDWM_WINDOW_METADATA_CHANGE_INSTANCE) {
|
||||||
|
state_window_set_instance(state, window_id, metadata->instance_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void route_window_activate_request(
|
||||||
|
state_t *state,
|
||||||
|
const window_activate_request_event_t *e,
|
||||||
|
command_buffer_t *out
|
||||||
|
) {
|
||||||
|
auto window = state_window_get(state, e->window);
|
||||||
|
if (!window) return;
|
||||||
|
|
||||||
|
switch (e->source) {
|
||||||
|
case ZDWM_WINDOW_ACTIVATION_SOURCE_LEGACY:
|
||||||
|
break;
|
||||||
|
case ZDWM_WINDOW_ACTIVATION_SOURCE_APPLICATION: {
|
||||||
|
command_t change_window_state_cmd = {
|
||||||
|
.type = ZDWM_COMMAND_CHANGE_WINDOW_STATE,
|
||||||
|
.as.state_change = {
|
||||||
|
.type = ZDWM_WINDOW_STATE_REQUEST_URGENT,
|
||||||
|
.window = window->id,
|
||||||
|
.action = ZDWM_WINDOW_STATE_ACTION_ADD,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
command_buffer_push(out, &change_window_state_cmd);
|
||||||
|
} break;
|
||||||
|
case ZDWM_WINDOW_ACTIVATION_SOURCE_PAGER: {
|
||||||
|
command_t switch_workspace_cmd = {
|
||||||
|
.type = ZDWM_COMMAND_SWITCH_WORKSPACE,
|
||||||
|
.as.switch_workspace.workspace = window->workspace_id,
|
||||||
|
};
|
||||||
|
command_buffer_push(out, &switch_workspace_cmd);
|
||||||
|
|
||||||
|
command_t focus_cmd = {
|
||||||
|
.type = ZDWM_COMMAND_FOCUS_WINDOW,
|
||||||
|
.as.focus.window = window->id,
|
||||||
|
};
|
||||||
|
command_buffer_push(out, &focus_cmd);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void route_window_state_request(
|
||||||
|
state_t *state,
|
||||||
|
const window_state_request_event_t *e,
|
||||||
|
command_buffer_t *out
|
||||||
|
) {
|
||||||
|
auto window = state_window_get(state, e->window);
|
||||||
|
if (!window) return;
|
||||||
|
|
||||||
|
command_t change_window_state_cmd = {
|
||||||
|
.type = ZDWM_COMMAND_CHANGE_WINDOW_STATE,
|
||||||
|
.as.state_change = {
|
||||||
|
.type = e->type,
|
||||||
|
.window = e->window,
|
||||||
|
.action = e->action,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
command_buffer_push(out, &change_window_state_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
static void route_configure_request(
|
static void route_configure_request(
|
||||||
state_t *state,
|
state_t *state,
|
||||||
const configure_data_t *data,
|
const configure_data_t *data,
|
||||||
@@ -190,6 +275,16 @@ void policy_route_event(
|
|||||||
case ZDWM_EVENT_WINDOW_REMOVE:
|
case ZDWM_EVENT_WINDOW_REMOVE:
|
||||||
route_window_remove(state, &event->as.window_remove, out);
|
route_window_remove(state, &event->as.window_remove, out);
|
||||||
break;
|
break;
|
||||||
|
case ZDWM_EVENT_WINDOW_METADATA_CHANGED:
|
||||||
|
route_window_metadata_changed(state, &event->as.window_metadata_change);
|
||||||
|
break;
|
||||||
|
case ZDWM_EVENT_WINDOW_ACTIVATE_REQUEST: {
|
||||||
|
auto data = &event->as.window_activate_request;
|
||||||
|
route_window_activate_request(state, data, out);
|
||||||
|
} break;
|
||||||
|
case ZDWM_EVENT_WINDOW_STATE_REQUEST:
|
||||||
|
route_window_state_request(state, &event->as.window_state_request, out);
|
||||||
|
break;
|
||||||
case ZDWM_EVENT_CONFIGURE_REQUEST: {
|
case ZDWM_EVENT_CONFIGURE_REQUEST: {
|
||||||
auto data = &event->as.configure_request;
|
auto data = &event->as.configure_request;
|
||||||
route_configure_request(state, data, ctx->layouts, out);
|
route_configure_request(state, data, ctx->layouts, out);
|
||||||
@@ -339,13 +434,14 @@ unmanage_window(const policy_context_t *ctx, window_id_t window, plan_t *plan) {
|
|||||||
auto workspace_id = win->workspace_id;
|
auto workspace_id = win->workspace_id;
|
||||||
auto workspace = state_workspace_get(state, workspace_id);
|
auto workspace = state_workspace_get(state, workspace_id);
|
||||||
auto output = state_output_get(state, workspace->output_id);
|
auto output = state_output_get(state, workspace->output_id);
|
||||||
|
auto need_layout = window_need_layout(win);
|
||||||
|
|
||||||
auto old_focused_window = workspace->focused_window_id;
|
auto old_focused_window = workspace->focused_window_id;
|
||||||
state_window_remove(state, window);
|
state_window_remove(state, window);
|
||||||
|
|
||||||
push_window_list_effect(state, plan);
|
push_window_list_effect(state, plan);
|
||||||
|
|
||||||
if (window_need_layout(win)) {
|
if (need_layout) {
|
||||||
adjust_layout_windows_border_width(state, ctx->border->width, workspace_id);
|
adjust_layout_windows_border_width(state, ctx->border->width, workspace_id);
|
||||||
plan->need_relayout = true;
|
plan->need_relayout = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -257,6 +257,59 @@ static void runtime_arrange(runtime_t *runtime) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
policy_context_t policy_context_init(runtime_t *runtime) {
|
||||||
|
policy_context_t ctx = {
|
||||||
|
.bind_table = (runtime)->binding_table,
|
||||||
|
.state = &(runtime)->state,
|
||||||
|
.rules = &(runtime)->rules,
|
||||||
|
.border = &(runtime)->border,
|
||||||
|
.layouts = &(runtime)->layouts,
|
||||||
|
.runtime = (runtime),
|
||||||
|
.action_api = {
|
||||||
|
.spawn = spawn,
|
||||||
|
.quit = quit,
|
||||||
|
.raise_or_run = raise_or_run,
|
||||||
|
.toggle_fullscreen = toggle_fullscreen,
|
||||||
|
.toggle_maximize = toggle_maximize,
|
||||||
|
.toggle_floating = toggle_floating,
|
||||||
|
.toggle_sticky = toggle_sticky,
|
||||||
|
.switch_workspace = switch_workspace,
|
||||||
|
.cycle_layout = cycle_layout,
|
||||||
|
.cycle_current_output = cycle_current_output,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void runtime_scan(runtime_t *runtime) {
|
||||||
|
auto result = backend_scan_windows(runtime->backend);
|
||||||
|
if (!result) return;
|
||||||
|
|
||||||
|
policy_context_t ctx = policy_context_init(runtime);
|
||||||
|
|
||||||
|
auto backend = runtime->backend;
|
||||||
|
auto command_buffer = &runtime->command_buffer;
|
||||||
|
auto plan = &runtime->plan;
|
||||||
|
|
||||||
|
command_buffer_reset(command_buffer);
|
||||||
|
plan_reset(plan);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < result->count; i++) {
|
||||||
|
event_t event = {
|
||||||
|
.type = ZDWM_EVENT_WINDOW_MAP_REQUEST,
|
||||||
|
.as.window_map_request = result->windows[i],
|
||||||
|
};
|
||||||
|
policy_route_event(&ctx, &event, command_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
policy_apply_command(&ctx, command_buffer, plan);
|
||||||
|
if (plan->need_relayout) runtime_arrange(runtime);
|
||||||
|
if (plan->count) backend_apply_effect(backend, plan->effects, plan->count);
|
||||||
|
|
||||||
|
backend_scan_result_destroy(result);
|
||||||
|
result = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void runtime_run(runtime_t *runtime) {
|
void runtime_run(runtime_t *runtime) {
|
||||||
runtime->running = true;
|
runtime->running = true;
|
||||||
|
|
||||||
@@ -264,19 +317,7 @@ void runtime_run(runtime_t *runtime) {
|
|||||||
command_buffer_t *command_buffer = &runtime->command_buffer;
|
command_buffer_t *command_buffer = &runtime->command_buffer;
|
||||||
plan_t *plan = &runtime->plan;
|
plan_t *plan = &runtime->plan;
|
||||||
|
|
||||||
policy_context_t ctx = {
|
policy_context_t ctx = policy_context_init(runtime);
|
||||||
.bind_table = runtime->binding_table,
|
|
||||||
.state = &runtime->state,
|
|
||||||
.rules = &runtime->rules,
|
|
||||||
.border = &runtime->border,
|
|
||||||
.layouts = &runtime->layouts,
|
|
||||||
.runtime = runtime,
|
|
||||||
.action_api = {
|
|
||||||
.spawn = spawn,
|
|
||||||
.quit = quit,
|
|
||||||
.raise_or_run = raise_or_run,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
while (runtime->running) {
|
while (runtime->running) {
|
||||||
event_t event = {0};
|
event_t event = {0};
|
||||||
|
|||||||
@@ -46,4 +46,5 @@ bool runtime_init(runtime_t *runtime, runtime_init_desc_t *desc);
|
|||||||
void runtime_init_desc_cleanup(runtime_init_desc_t *desc);
|
void runtime_init_desc_cleanup(runtime_init_desc_t *desc);
|
||||||
void runtime_shutdown(runtime_t *runtime);
|
void runtime_shutdown(runtime_t *runtime);
|
||||||
void runtime_setup(runtime_t *runtime);
|
void runtime_setup(runtime_t *runtime);
|
||||||
|
void runtime_scan(runtime_t *runtime);
|
||||||
void runtime_run(runtime_t *runtime);
|
void runtime_run(runtime_t *runtime);
|
||||||
|
|||||||
@@ -145,24 +145,35 @@ static void state_workspace_adjust_focused_window(
|
|||||||
workspace->focused_window_id = ZDWM_WINDOW_ID_INVALID;
|
workspace->focused_window_id = ZDWM_WINDOW_ID_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool state_workspace_cycle_layout(state_t *state, workspace_id_t workspace_id) {
|
bool state_workspace_cycle_layout(
|
||||||
|
state_t *state,
|
||||||
|
workspace_id_t workspace_id,
|
||||||
|
int32_t delta
|
||||||
|
) {
|
||||||
workspace_t *workspace =
|
workspace_t *workspace =
|
||||||
(workspace_t *)state_workspace_get(state, workspace_id);
|
(workspace_t *)state_workspace_get(state, workspace_id);
|
||||||
if (!workspace) return false;
|
if (!workspace) return false;
|
||||||
|
|
||||||
size_t next_index = 0;
|
int32_t index = 0;
|
||||||
bool matched = false;
|
bool matched = false;
|
||||||
for (size_t i = 0; i < workspace->layout_count; i++) {
|
auto layout_count = (int32_t)workspace->layout_count;
|
||||||
|
for (int32_t i = 0; i < layout_count; i++) {
|
||||||
if (workspace->layout_id == workspace->available_layouts[i]) {
|
if (workspace->layout_id == workspace->available_layouts[i]) {
|
||||||
next_index = (i + 1) % workspace->layout_count;
|
index = i;
|
||||||
matched = true;
|
matched = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!matched) return false;
|
if (!matched) return false;
|
||||||
|
|
||||||
auto next_layout_id = workspace->available_layouts[next_index];
|
auto new_index = index + delta;
|
||||||
|
new_index %= layout_count;
|
||||||
|
if (new_index < 0) new_index += layout_count;
|
||||||
|
|
||||||
|
if (new_index == index) return false;
|
||||||
|
|
||||||
|
auto next_layout_id = workspace->available_layouts[new_index];
|
||||||
workspace->layout_id = next_layout_id;
|
workspace->layout_id = next_layout_id;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -344,6 +355,7 @@ const window_t *state_window_add(state_t *state, const window_info_t *info) {
|
|||||||
window_set_urgent(window, info->urgent);
|
window_set_urgent(window, info->urgent);
|
||||||
window_set_fixed_size(window, info->fixed_size);
|
window_set_fixed_size(window, info->fixed_size);
|
||||||
window_set_frame_rect(window, info->frame_rect);
|
window_set_frame_rect(window, info->frame_rect);
|
||||||
|
window_set_float_rect(window, info->frame_rect);
|
||||||
window_set_title(window, info->title);
|
window_set_title(window, info->title);
|
||||||
window_set_app_id(window, info->app_id);
|
window_set_app_id(window, info->app_id);
|
||||||
window_set_role(window, info->role);
|
window_set_role(window, info->role);
|
||||||
|
|||||||
@@ -81,7 +81,11 @@ void state_cleanup(state_t *state);
|
|||||||
*/
|
*/
|
||||||
const workspace_t *state_workspace_get(const state_t *state, workspace_id_t id);
|
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);
|
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_cycle_layout(
|
||||||
|
state_t *state,
|
||||||
|
workspace_id_t workspace_id,
|
||||||
|
int32_t delta
|
||||||
|
);
|
||||||
bool state_workspace_set_layout_by_index(
|
bool state_workspace_set_layout_by_index(
|
||||||
state_t *state,
|
state_t *state,
|
||||||
workspace_id_t workspace_id,
|
workspace_id_t workspace_id,
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ void window_set_floating(window_t *window, bool floating) {
|
|||||||
if (floating == window->floating) return;
|
if (floating == window->floating) return;
|
||||||
|
|
||||||
window->floating = floating;
|
window->floating = floating;
|
||||||
if (floating) window->float_rect = window->frame_rect;
|
if (floating) window_set_frame_rect(window, window->float_rect);
|
||||||
|
else window_set_float_rect(window, window->frame_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_set_sticky(window_t *window, bool sticky) {
|
void window_set_sticky(window_t *window, bool sticky) {
|
||||||
|
|||||||
Reference in New Issue
Block a user