Compare commits
4 Commits
cdcafa1216
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
a5d31cccdd
|
|||
|
86a89452a7
|
|||
| 123fe77bbb | |||
| 1ec92ec3e2 |
10
src/action.c
10
src/action.c
@@ -8,6 +8,7 @@
|
||||
#include "monitor.h"
|
||||
#include "types.h"
|
||||
#include "wm.h"
|
||||
#include "xcursor.h"
|
||||
|
||||
void focus_client_in_same_tag(const user_action_arg_t *arg) {
|
||||
bool next = arg->b;
|
||||
@@ -72,9 +73,16 @@ void quit(const user_action_arg_t *arg) {
|
||||
void raise_or_run(const user_action_arg_t *arg) {
|
||||
const char *class = ((const char **)arg->ptr)[0];
|
||||
client_t *client = client_get_next_by_class(wm.client_focused, class);
|
||||
if (client && client == wm.client_focused) return;
|
||||
|
||||
if (client) {
|
||||
bool monitor_changed = client->monitor != wm.current_monitor;
|
||||
bool tag_changed = client->tags != client->monitor->selected_tag->mask;
|
||||
if (monitor_changed || tag_changed) {
|
||||
point_t point = monitor_changed ? monitor_get_restore_cursor_point(
|
||||
client->monitor)
|
||||
: xcursor_query_pointer_position();
|
||||
wm_ignore_enter_notify_at_point(point);
|
||||
}
|
||||
wm_set_current_monitor(client->monitor, true);
|
||||
monitor_select_tag(client->monitor, client->tags);
|
||||
client_stack_raise(client);
|
||||
|
||||
@@ -27,6 +27,7 @@ _NET_WM_STATE
|
||||
_NET_WM_STATE_FULLSCREEN
|
||||
_NET_WM_STATE_MAXIMIZED_HORZ
|
||||
_NET_WM_STATE_MAXIMIZED_VERT
|
||||
_NET_WM_STATE_SKIP_TASKBAR
|
||||
_NET_WM_WINDOW_TYPE
|
||||
_NET_WM_WINDOW_TYPE_DIALOG
|
||||
_NET_SUPPORTED
|
||||
|
||||
@@ -366,6 +366,7 @@ void client_update_window_type(client_t *client) {
|
||||
|
||||
if (state_reply) {
|
||||
xcb_atom_t state = *(xcb_atom_t *)xcb_get_property_value(state_reply);
|
||||
client->skip_taskbar = state == _NET_WM_STATE_SKIP_TASKBAR;
|
||||
if (state == _NET_WM_STATE_FULLSCREEN) {
|
||||
client_set_fullscreen(client, true);
|
||||
}
|
||||
|
||||
@@ -105,6 +105,8 @@ static const char browser[] = "firefox-bin";
|
||||
static const char browser_class[] = "firefox";
|
||||
static const char chrome[] = "google-chrome-stable";
|
||||
static const char chrome_class[] = "Google-chrome";
|
||||
static const char mpv[] = "mpv";
|
||||
static const char mpv_class[] = "mpv";
|
||||
static const keyboard_t key_list[] = {
|
||||
{modifier_super, XK_r, spawn, {.ptr = launcher}},
|
||||
{modifier_super, XK_Return, spawn, {.ptr = terminal}},
|
||||
@@ -132,6 +134,12 @@ static const keyboard_t key_list[] = {
|
||||
raise_or_run,
|
||||
{.ptr = (const char *[]){chrome_class, chrome}},
|
||||
},
|
||||
{
|
||||
modifier_super,
|
||||
XK_v,
|
||||
raise_or_run,
|
||||
{.ptr = (const char *[]){mpv_class, mpv}},
|
||||
},
|
||||
{modifier_super | modifier_shift, XK_q, quit, {.b = false}},
|
||||
{modifier_super | modifier_control, XK_r, quit, {.b = true}},
|
||||
{modifier_super | modifier_shift,
|
||||
|
||||
10
src/event.c
10
src/event.c
@@ -313,16 +313,13 @@ static void expose(xcb_expose_event_t *ev) {
|
||||
}
|
||||
|
||||
static void enter_notify(xcb_enter_notify_event_t *ev) {
|
||||
if (wm_should_ignore_enter_notify(ev)) return;
|
||||
|
||||
client_t *client = client_get_by_window(ev->event);
|
||||
if (!client || wm.client_focused == client) return;
|
||||
|
||||
client_focus(client);
|
||||
}
|
||||
|
||||
static void focus_in(xcb_focus_in_event_t *ev) {
|
||||
client_t *client = client_get_by_window(ev->event);
|
||||
if (!client) return;
|
||||
wm_set_current_monitor(client->monitor, ev->mode != XCB_NOTIFY_MODE_NORMAL);
|
||||
wm_set_current_monitor(client->monitor, false);
|
||||
}
|
||||
|
||||
static void selection_clear(xcb_selection_clear_event_t *ev) {
|
||||
@@ -353,7 +350,6 @@ static void handle_xcb_event(xcb_generic_event_t *event) {
|
||||
EVENT(XCB_UNMAP_NOTIFY, unmap_notify);
|
||||
EVENT(XCB_DESTROY_NOTIFY, destroy_notify);
|
||||
EVENT(XCB_ENTER_NOTIFY, enter_notify);
|
||||
EVENT(XCB_FOCUS_IN, focus_in);
|
||||
EVENT(XCB_SELECTION_CLEAR, selection_clear);
|
||||
|
||||
#undef EVENT
|
||||
|
||||
@@ -350,7 +350,10 @@ static void monitor_draw_tasks(monitor_t *monitor, int16_t right_edge) {
|
||||
if (!task_list) return;
|
||||
|
||||
uint16_t task_count = 0;
|
||||
for (task_in_tag_t *task = task_list; task; task = task->next) ++task_count;
|
||||
for (task_in_tag_t *task = task_list; task; task = task->next) {
|
||||
if (task->client->skip_taskbar) continue;
|
||||
++task_count;
|
||||
};
|
||||
if (task_count == 0) return;
|
||||
|
||||
int16_t x = monitor->layout_symbol_extent.end;
|
||||
@@ -361,6 +364,8 @@ static void monitor_draw_tasks(monitor_t *monitor, int16_t right_edge) {
|
||||
if (task_width < wm.font_size) return;
|
||||
|
||||
for (task_in_tag_t *task = task_list; task; task = task->next) {
|
||||
if (task->client->skip_taskbar) continue;
|
||||
|
||||
task->bar_extent.start = x;
|
||||
task->bar_extent.end = x + task_width;
|
||||
x += task_width;
|
||||
@@ -432,7 +437,7 @@ void monitor_save_cursor_point(monitor_t *monitor) {
|
||||
monitor->position_inited = true;
|
||||
}
|
||||
|
||||
void monitor_restore_cursor_point(monitor_t *monitor) {
|
||||
point_t monitor_get_restore_cursor_point(monitor_t *monitor) {
|
||||
if (!monitor->position_inited) {
|
||||
point_t point = xcursor_query_pointer_position();
|
||||
monitor_t *m = wm_get_monitor_by_point(point);
|
||||
@@ -441,5 +446,9 @@ void monitor_restore_cursor_point(monitor_t *monitor) {
|
||||
monitor->position_inited = true;
|
||||
}
|
||||
|
||||
xcursor_set_pointer_position(monitor->cursor_position);
|
||||
return monitor->cursor_position;
|
||||
}
|
||||
|
||||
void monitor_restore_cursor_point(monitor_t *monitor) {
|
||||
xcursor_set_pointer_position(monitor_get_restore_cursor_point(monitor));
|
||||
}
|
||||
|
||||
@@ -13,4 +13,5 @@ void monitor_init_bar(monitor_t *monitor);
|
||||
void monitor_draw_bar(monitor_t *monitor);
|
||||
void monitor_arrange(monitor_t *monitor);
|
||||
void monitor_save_cursor_point(monitor_t *monitor);
|
||||
point_t monitor_get_restore_cursor_point(monitor_t *monitor);
|
||||
void monitor_restore_cursor_point(monitor_t *monitor);
|
||||
|
||||
@@ -38,6 +38,7 @@ struct client_t {
|
||||
bool minimize;
|
||||
bool sticky;
|
||||
bool urgent;
|
||||
bool skip_taskbar;
|
||||
bool size_freeze; /* 尺寸冻结窗口一定是浮动窗口 */
|
||||
|
||||
char *class, *instance;
|
||||
|
||||
40
src/wm.c
40
src/wm.c
@@ -57,6 +57,7 @@ static void wm_update_status(status_t *status);
|
||||
static void wm_run_autostart(const char *const commands[]);
|
||||
static void run_once(const char *command);
|
||||
static bool command_already_running(const char *command);
|
||||
static gboolean clear_ignore_enter_notify(gpointer data);
|
||||
|
||||
wm_t wm;
|
||||
|
||||
@@ -81,6 +82,39 @@ static void signal_fatal(int signal_number) {
|
||||
|
||||
static guint sources[3] = {0};
|
||||
|
||||
static gboolean clear_ignore_enter_notify(gpointer data) {
|
||||
wm.ignore_enter_notify = false;
|
||||
wm.ignored_enter_notify_point = (point_t){0};
|
||||
wm.clear_ignore_enter_notify_source = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
void wm_ignore_enter_notify_at_point(point_t point) {
|
||||
wm.ignore_enter_notify = true;
|
||||
wm.ignored_enter_notify_point = point;
|
||||
if (wm.clear_ignore_enter_notify_source) {
|
||||
g_source_remove(wm.clear_ignore_enter_notify_source);
|
||||
}
|
||||
wm.clear_ignore_enter_notify_source =
|
||||
g_idle_add(clear_ignore_enter_notify, nullptr);
|
||||
}
|
||||
|
||||
bool wm_should_ignore_enter_notify(const xcb_enter_notify_event_t *ev) {
|
||||
if (!wm.ignore_enter_notify) return false;
|
||||
if (ev->root_x != wm.ignored_enter_notify_point.x ||
|
||||
ev->root_y != wm.ignored_enter_notify_point.y) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (wm.clear_ignore_enter_notify_source) {
|
||||
g_source_remove(wm.clear_ignore_enter_notify_source);
|
||||
wm.clear_ignore_enter_notify_source = 0;
|
||||
}
|
||||
wm.ignore_enter_notify = false;
|
||||
wm.ignored_enter_notify_point = (point_t){0};
|
||||
return true;
|
||||
}
|
||||
|
||||
void wm_setup_signal(void) {
|
||||
sources[0] = g_unix_signal_add(SIGINT, exit_on_signal, nullptr);
|
||||
sources[1] = g_unix_signal_add(SIGTERM, exit_on_signal, nullptr);
|
||||
@@ -405,6 +439,12 @@ void wm_clean(void) {
|
||||
guint source_id = sources[i];
|
||||
if (source_id) g_source_remove(source_id);
|
||||
}
|
||||
if (wm.clear_ignore_enter_notify_source) {
|
||||
g_source_remove(wm.clear_ignore_enter_notify_source);
|
||||
wm.clear_ignore_enter_notify_source = 0;
|
||||
}
|
||||
wm.ignore_enter_notify = false;
|
||||
wm.ignored_enter_notify_point = (point_t){0};
|
||||
|
||||
xcb_delete_property(wm.xcb_conn, wm.screen->root, _NET_ACTIVE_WINDOW);
|
||||
xcb_delete_property(wm.xcb_conn, wm.screen->root, _NET_SUPPORTING_WM_CHECK);
|
||||
|
||||
5
src/wm.h
5
src/wm.h
@@ -28,6 +28,9 @@ typedef struct wm_t {
|
||||
client_t *client_focused;
|
||||
monitor_t *monitor_list;
|
||||
monitor_t *current_monitor;
|
||||
bool ignore_enter_notify;
|
||||
point_t ignored_enter_notify_point;
|
||||
guint clear_ignore_enter_notify_source;
|
||||
const layout_t *layout_list;
|
||||
|
||||
char *font_family;
|
||||
@@ -63,6 +66,8 @@ extern wm_t wm;
|
||||
void wm_restart(void);
|
||||
void wm_quit(void);
|
||||
void wm_restack_clients(void);
|
||||
void wm_ignore_enter_notify_at_point(point_t point);
|
||||
bool wm_should_ignore_enter_notify(const xcb_enter_notify_event_t *ev);
|
||||
void wm_set_current_monitor(monitor_t *monitor, bool restore_cursor);
|
||||
monitor_t *__attribute__((returns_nonnull)) wm_get_monitor_by_area(area_t area);
|
||||
monitor_t *__attribute__((returns_nonnull)) wm_get_monitor_by_point(
|
||||
|
||||
Reference in New Issue
Block a user