支持窗口全屏操作
This commit is contained in:
@@ -81,3 +81,9 @@ void toggle_client_floating(const user_action_arg_t *arg) {
|
|||||||
|
|
||||||
client_set_floating(wm.client_focused, !wm.client_focused->floating);
|
client_set_floating(wm.client_focused, !wm.client_focused->floating);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void toggle_client_fullscreen(const user_action_arg_t *arg) {
|
||||||
|
if (!wm.client_focused) return;
|
||||||
|
|
||||||
|
client_set_fullscreen(wm.client_focused, !wm.client_focused->fullscreen);
|
||||||
|
}
|
||||||
|
|||||||
@@ -56,3 +56,4 @@ void spawn(const user_action_arg_t *arg);
|
|||||||
void quit(const user_action_arg_t *arg);
|
void quit(const user_action_arg_t *arg);
|
||||||
void raise_or_run(const user_action_arg_t *arg);
|
void raise_or_run(const user_action_arg_t *arg);
|
||||||
void toggle_client_floating(const user_action_arg_t *arg);
|
void toggle_client_floating(const user_action_arg_t *arg);
|
||||||
|
void toggle_client_fullscreen(const user_action_arg_t *arg);
|
||||||
|
|||||||
@@ -14,4 +14,7 @@ _NET_CLIENT_LIST
|
|||||||
_NET_WM_DESKTOP
|
_NET_WM_DESKTOP
|
||||||
_NET_WM_NAME
|
_NET_WM_NAME
|
||||||
_NET_WM_ICON_NAME
|
_NET_WM_ICON_NAME
|
||||||
|
_NET_WM_STATE
|
||||||
|
_NET_WM_STATE_FULLSCREEN
|
||||||
|
_NET_SUPPORTED
|
||||||
_NET_SUPPORTING_WM_CHECK
|
_NET_SUPPORTING_WM_CHECK
|
||||||
|
|||||||
18
src/atoms.c
18
src/atoms.c
@@ -1,9 +1,12 @@
|
|||||||
#include "atoms.h"
|
#include "atoms.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
|
|
||||||
#include "atoms-intern.h"
|
#include "atoms-intern.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "wm.h"
|
||||||
|
|
||||||
void atoms_init(xcb_connection_t *conn) {
|
void atoms_init(xcb_connection_t *conn) {
|
||||||
xcb_intern_atom_cookie_t cookies[countof(ATOM_LIST)];
|
xcb_intern_atom_cookie_t cookies[countof(ATOM_LIST)];
|
||||||
@@ -12,12 +15,25 @@ void atoms_init(xcb_connection_t *conn) {
|
|||||||
cookies[i] = xcb_intern_atom_unchecked(conn, false, atom.len, atom.name);
|
cookies[i] = xcb_intern_atom_unchecked(conn, false, atom.len, atom.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
atom_item_t *atom = nullptr;
|
||||||
|
uint32_t supported_length = 0;
|
||||||
|
xcb_atom_t supported_list[countof(ATOM_LIST)] = {XCB_ATOM_NONE};
|
||||||
|
|
||||||
xcb_intern_atom_reply_t *reply = nullptr;
|
xcb_intern_atom_reply_t *reply = nullptr;
|
||||||
for (int i = 0; i < countof(ATOM_LIST); i++) {
|
for (int i = 0; i < countof(ATOM_LIST); i++) {
|
||||||
reply = xcb_intern_atom_reply(conn, cookies[i], nullptr);
|
reply = xcb_intern_atom_reply(conn, cookies[i], nullptr);
|
||||||
if (reply) {
|
if (reply) {
|
||||||
*ATOM_LIST[i].atom = reply->atom;
|
atom = &ATOM_LIST[i];
|
||||||
|
*atom->atom = reply->atom;
|
||||||
p_delete(&reply);
|
p_delete(&reply);
|
||||||
|
|
||||||
|
if (strstr(atom->name, "_NET_") == atom->name) {
|
||||||
|
supported_list[supported_length++] = *atom->atom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_change_property(wm.xcb_conn, XCB_PROP_MODE_REPLACE, wm.screen->root,
|
||||||
|
_NET_SUPPORTED, XCB_ATOM_ATOM, 32, supported_length,
|
||||||
|
supported_list);
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/client.c
22
src/client.c
@@ -362,6 +362,28 @@ void client_set_floating(client_t *client, bool floating) {
|
|||||||
monitor_arrange(client->monitor);
|
monitor_arrange(client->monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void client_set_fullscreen(client_t *client, bool fullscreen) {
|
||||||
|
if (client->fullscreen == fullscreen) return;
|
||||||
|
|
||||||
|
client->fullscreen = fullscreen;
|
||||||
|
if (fullscreen) {
|
||||||
|
xcb_change_property(wm.xcb_conn, XCB_PROP_MODE_REPLACE, client->window,
|
||||||
|
_NET_WM_STATE, XCB_ATOM_ATOM, 32, 1,
|
||||||
|
&_NET_WM_STATE_FULLSCREEN);
|
||||||
|
client->old_border_width = client->border_width;
|
||||||
|
client_change_border_width(client, 0);
|
||||||
|
client_apply_geometry(client, client->monitor->geometry);
|
||||||
|
client_stack_raise(client);
|
||||||
|
} else {
|
||||||
|
xcb_change_property(wm.xcb_conn, XCB_PROP_MODE_REPLACE, client->window,
|
||||||
|
_NET_WM_STATE, XCB_ATOM_ATOM, 32, 0, 0);
|
||||||
|
client_change_border_width(client, client->old_border_width);
|
||||||
|
client_apply_geometry(client, client->old_geometry);
|
||||||
|
monitor_arrange(client->monitor);
|
||||||
|
}
|
||||||
|
client_focus(client);
|
||||||
|
}
|
||||||
|
|
||||||
static void update_client_list(void) {
|
static void update_client_list(void) {
|
||||||
xcb_connection_t *conn = wm.xcb_conn;
|
xcb_connection_t *conn = wm.xcb_conn;
|
||||||
xcb_window_t root = wm.screen->root;
|
xcb_window_t root = wm.screen->root;
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ static const keyboard_t key_list[] = {
|
|||||||
{modifier_super, XK_o, send_client_to_next_monitor, {0}},
|
{modifier_super, XK_o, send_client_to_next_monitor, {0}},
|
||||||
|
|
||||||
{modifier_super | modifier_control, XK_space, toggle_client_floating, {0}},
|
{modifier_super | modifier_control, XK_space, toggle_client_floating, {0}},
|
||||||
|
{modifier_super, XK_f, toggle_client_fullscreen, {0}},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const layout_t layout_list[] = {
|
static const layout_t layout_list[] = {
|
||||||
|
|||||||
21
src/event.c
21
src/event.c
@@ -144,6 +144,27 @@ static void client_message(xcb_client_message_event_t *ev) {
|
|||||||
client_focus(c);
|
client_focus(c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else if (ev->type == _NET_WM_STATE) {
|
||||||
|
/**
|
||||||
|
* _NET_WM_STATE 协议数据格式为
|
||||||
|
* data.data32 = {
|
||||||
|
* action, // 操作类型(添加/移除/切换)
|
||||||
|
* property1, // 第一个状态原子(如_NET_WM_STATE_FULLSCREEN)
|
||||||
|
* property2, // 第二个状态原子(可选,通常为0)
|
||||||
|
* 0, // 预留字段(固定为0)
|
||||||
|
* 0 // 预留字段(固定为0)
|
||||||
|
* };
|
||||||
|
* action 值可能为
|
||||||
|
* _NET_WM_STATE_ADD(1):添加全屏状态,窗口进入全屏模式
|
||||||
|
* _NET_WM_STATE_REMOVE(0):移除全屏状态,窗口退出全屏模式
|
||||||
|
* _NET_WM_STATE_TOGGLE(2):切换全屏状态(若当前全屏则退出,反之进入)
|
||||||
|
*/
|
||||||
|
if (ev->data.data32[1] == _NET_WM_STATE_FULLSCREEN ||
|
||||||
|
ev->data.data32[2] == _NET_WM_STATE_FULLSCREEN) {
|
||||||
|
bool fullscreen = ev->data.data32[0];
|
||||||
|
if (ev->data.data32[0] == 2) fullscreen = !c->fullscreen;
|
||||||
|
client_set_fullscreen(c, fullscreen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user