Compare commits
4 Commits
c5e79661d1
...
6382afeb03
| Author | SHA1 | Date | |
|---|---|---|---|
|
6382afeb03
|
|||
|
dee16344ce
|
|||
|
94d3aa669f
|
|||
|
b944251f11
|
19
src/action.c
19
src/action.c
@@ -3,9 +3,28 @@
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "client.h"
|
||||
#include "monitor.h"
|
||||
#include "types.h"
|
||||
#include "wm.h"
|
||||
|
||||
void focus_client_in_same_tag(const user_action_arg_t *arg) {
|
||||
bool next = arg->b;
|
||||
tag_t *tag = wm.current_monitor->selected_tag;
|
||||
|
||||
task_in_tag_t *task = nullptr;
|
||||
if (next) {
|
||||
task = client_get_next_task_in_tag(wm.client_focused, tag);
|
||||
} else {
|
||||
task = client_get_previous_task_in_tag(wm.client_focused, tag);
|
||||
}
|
||||
|
||||
if (!task) return;
|
||||
|
||||
client_stack_raise(task->client);
|
||||
client_focus(task->client);
|
||||
}
|
||||
|
||||
void select_tag_of_current_monitor(const user_action_arg_t *arg) {
|
||||
monitor_select_tag(wm.current_monitor, arg->ui);
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ typedef struct keyboard_t {
|
||||
const user_action_arg_t arg;
|
||||
} keyboard_t;
|
||||
|
||||
void focus_client_in_same_tag(const user_action_arg_t *arg);
|
||||
void select_tag_of_current_monitor(const user_action_arg_t *arg);
|
||||
void spawn(const user_action_arg_t *arg);
|
||||
void quit(const user_action_arg_t *arg);
|
||||
|
||||
32
src/client.c
32
src/client.c
@@ -58,6 +58,22 @@ task_in_tag_t *client_get_task_in_tag(client_t *client, tag_t *tag) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
task_in_tag_t *client_get_next_task_in_tag(client_t *client, tag_t *tag) {
|
||||
if (!tag->task_list) return nullptr;
|
||||
|
||||
task_in_tag_t *task = tag->task_list;
|
||||
for (; task && task->client != client; task = task->next);
|
||||
return task && task->next ? task->next : tag->task_list;
|
||||
}
|
||||
|
||||
task_in_tag_t *client_get_previous_task_in_tag(client_t *client, tag_t *tag) {
|
||||
if (!tag->task_list) return nullptr;
|
||||
|
||||
task_in_tag_t *task = tag->task_list;
|
||||
for (; task && task->next && task->next->client != client; task = task->next);
|
||||
return task ? task : tag->task_list;
|
||||
}
|
||||
|
||||
static void client_add_to_tag(client_t *client, tag_t *tag) {
|
||||
if (client_get_task_in_tag(client, tag)) return;
|
||||
|
||||
@@ -191,6 +207,9 @@ void client_manage(xcb_window_t window,
|
||||
monitor_arrange(c->monitor);
|
||||
monitor_draw_bar(c->monitor);
|
||||
|
||||
wm_restack_clients();
|
||||
if (c->tags & c->monitor->selected_tag->mask) client_focus(c);
|
||||
|
||||
xcb_flush(wm.xcb_conn);
|
||||
}
|
||||
|
||||
@@ -277,6 +296,8 @@ void client_unmanage(client_t *client) {
|
||||
|
||||
client_wipe(client);
|
||||
|
||||
wm_restack_clients();
|
||||
monitor_deal_focus(m);
|
||||
monitor_arrange(m);
|
||||
monitor_draw_bar(m);
|
||||
xcb_flush(wm.xcb_conn);
|
||||
@@ -295,6 +316,17 @@ void client_apply_task_geometry(client_t *client, task_in_tag_t *task) {
|
||||
}
|
||||
}
|
||||
|
||||
void client_focus(client_t *client) {
|
||||
wm.client_focused = client;
|
||||
xwindow_focus(client ? client->window : XCB_WINDOW_NONE);
|
||||
}
|
||||
|
||||
void client_stack_raise(client_t *client) {
|
||||
client_detach_stack(client);
|
||||
client_attach_stack(client);
|
||||
wm_restack_clients();
|
||||
}
|
||||
|
||||
bool client_is_visible(client_t *client) {
|
||||
return client->tags & client->monitor->selected_tag->mask;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
client_t *client_get_by_window(xcb_window_t window);
|
||||
task_in_tag_t *client_get_task_in_tag(client_t *client, tag_t *tag);
|
||||
task_in_tag_t *client_get_next_task_in_tag(client_t *client, tag_t *tag);
|
||||
task_in_tag_t *client_get_previous_task_in_tag(client_t *client, tag_t *tag);
|
||||
void client_manage(xcb_window_t window,
|
||||
xcb_get_geometry_reply_t *geometry_reply);
|
||||
char **client_get_task_title(client_t *client);
|
||||
|
||||
@@ -36,6 +36,8 @@ static const keyboard_t key_list[] = {
|
||||
{modifier_alt, XK_p, spawn, {.ptr = launcher}},
|
||||
{modifier_alt, XK_q, quit, {.b = false}},
|
||||
{modifier_alt, XK_r, quit, {.b = true}},
|
||||
{modifier_alt | modifier_shift, XK_j, focus_client_in_same_tag, {.b = true}},
|
||||
{modifier_alt | modifier_shift, XK_k, focus_client_in_same_tag, {.b = false}},
|
||||
};
|
||||
|
||||
static const layout_t layout_list[] = {
|
||||
|
||||
@@ -48,17 +48,33 @@ uint32_t monitor_initialize_tag(monitor_t *monitor, const char **tags,
|
||||
return tag_count;
|
||||
}
|
||||
|
||||
void monitor_deal_focus(monitor_t *monitor) {
|
||||
if (!monitor->selected_tag->task_list) return;
|
||||
|
||||
client_t *client = nullptr;
|
||||
for (client_t *c = wm.client_stack_list; c; c = c->stack_next) {
|
||||
if (client_get_task_in_tag(c, monitor->selected_tag)) {
|
||||
client = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
client_focus(client);
|
||||
}
|
||||
|
||||
void monitor_select_tag(monitor_t *monitor, uint32_t tag_mask) {
|
||||
if (monitor->selected_tag->mask == tag_mask) return;
|
||||
|
||||
for (tag_t *tag = monitor->tag_list; tag; tag = tag->next) {
|
||||
if (tag->mask == tag_mask) {
|
||||
monitor->selected_tag = tag;
|
||||
monitor_arrange(monitor);
|
||||
monitor_draw_bar(monitor);
|
||||
xcb_flush(wm.xcb_conn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
monitor_deal_focus(monitor);
|
||||
}
|
||||
|
||||
static void tag_clean(tag_t *tag) {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
uint32_t monitor_initialize_tag(monitor_t *monitor, const char **tags,
|
||||
uint32_t tag_index_start_at);
|
||||
void monitor_deal_focus(monitor_t *monitor);
|
||||
void monitor_select_tag(monitor_t *monitor, uint32_t tag_mask);
|
||||
void monitor_clean(monitor_t *monitor);
|
||||
void monitor_init_bar(monitor_t *monitor);
|
||||
|
||||
19
src/wm.c
19
src/wm.c
@@ -390,6 +390,25 @@ void wm_quit(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void wm_restack_clients(void) {
|
||||
xcb_window_t sibling_window = XCB_WINDOW_NONE;
|
||||
for (client_t *c = wm.client_stack_list; c; c = c->stack_next) {
|
||||
uint16_t mask = XCB_CONFIG_WINDOW_STACK_MODE;
|
||||
xcb_params_configure_window_t params = {};
|
||||
if (sibling_window == XCB_WINDOW_NONE) {
|
||||
mask = XCB_CONFIG_WINDOW_STACK_MODE;
|
||||
params.stack_mode = XCB_STACK_MODE_ABOVE;
|
||||
} else {
|
||||
mask = XCB_CONFIG_WINDOW_STACK_MODE | XCB_CONFIG_WINDOW_SIBLING;
|
||||
params.stack_mode = XCB_STACK_MODE_BELOW;
|
||||
params.sibling = sibling_window;
|
||||
}
|
||||
sibling_window = c->window;
|
||||
xcb_aux_configure_window(wm.xcb_conn, c->window, mask, ¶ms);
|
||||
}
|
||||
xcb_flush(wm.xcb_conn);
|
||||
}
|
||||
|
||||
static void debug_show_monitor_list(void) {
|
||||
logger("\n========================== monitors ==========================\n");
|
||||
for (monitor_t *m = wm.monitor_list; m; m = m->next) {
|
||||
|
||||
1
src/wm.h
1
src/wm.h
@@ -51,3 +51,4 @@ extern wm_t wm;
|
||||
|
||||
void wm_restart(void);
|
||||
void wm_quit(void);
|
||||
void wm_restack_clients(void);
|
||||
|
||||
@@ -187,6 +187,8 @@ void xwindow_get_text_property(xcb_window_t window, xcb_atom_t property,
|
||||
wm.xcb_conn, false, window, property, XCB_ATOM_ANY, 0, UINT32_MAX);
|
||||
xcb_get_property_reply_t *reply =
|
||||
xcb_get_property_reply(wm.xcb_conn, cookie, nullptr);
|
||||
if (!reply) return;
|
||||
|
||||
int length = xcb_get_property_value_length(reply);
|
||||
char *value = xcb_get_property_value(reply);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user