support fullscreen toggle
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
cerberus
|
cerberus
|
||||||
========
|
========
|
||||||
|
|
||||||
* Designed for wide screens.
|
* Designed for wide screens, including multi-head support.
|
||||||
* Static tiling; you get just three fixed asymmetric tiles and windows never move automatically.
|
* Static tiling; you get just three fixed asymmetric tiles and windows never move automatically.
|
||||||
* Bare minimum EWMH to support panels and [simpleswitcher](https://github.com/seanpringle/simpleswitcher)
|
* Bare minimum EWMH to support panels and [simpleswitcher](https://github.com/seanpringle/simpleswitcher)
|
||||||
* A few keyboard controls for moving, focusing, cycling, closing, and finding windows.
|
* A few keyboard controls for moving, focusing, cycling, closing, and finding windows.
|
||||||
|
|||||||
67
cerberus.c
67
cerberus.c
@@ -182,6 +182,8 @@ client* window_client(Window win)
|
|||||||
? (c->attr.y > m->y + m->h/2 ? SPOT3: SPOT2)
|
? (c->attr.y > m->y + m->h/2 ? SPOT3: SPOT2)
|
||||||
: SPOT1;
|
: SPOT1;
|
||||||
|
|
||||||
|
window_get_atom_prop(c->window, atoms[_NET_WM_STATE], c->states, MAX_NET_WM_STATES);
|
||||||
|
|
||||||
if (c->visible)
|
if (c->visible)
|
||||||
{
|
{
|
||||||
XWMHints *hints = XGetWMHints(display, c->window);
|
XWMHints *hints = XGetWMHints(display, c->window);
|
||||||
@@ -202,6 +204,55 @@ client* window_client(Window win)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check _NET_WM_STATE
|
||||||
|
int client_state(client *c, Atom state)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < MAX_NET_WM_STATES && c->states[i]; i++)
|
||||||
|
if (c->states[i] == state)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int client_add_state(client *c, Atom state)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < MAX_NET_WM_STATES; i++)
|
||||||
|
{
|
||||||
|
if (c->states[i]) continue;
|
||||||
|
|
||||||
|
c->states[i] = state;
|
||||||
|
window_set_atom_prop(c->window, atoms[_NET_WM_STATE], c->states, i+1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int client_drop_state(client *c, Atom state)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
for (i = 0, j = 0; i < MAX_NET_WM_STATES && c->states[i]; i++)
|
||||||
|
{
|
||||||
|
if (c->states[i] == state) continue;
|
||||||
|
c->states[i] = c->states[j++];
|
||||||
|
}
|
||||||
|
window_set_atom_prop(c->window, atoms[_NET_WM_STATE], c->states, j);
|
||||||
|
int rc = i != j ? 1:0;
|
||||||
|
|
||||||
|
for (; j < MAX_NET_WM_STATES; j++)
|
||||||
|
c->states[j] = None;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void client_toggle_state(client *c, Atom state)
|
||||||
|
{
|
||||||
|
if (client_state(c, state))
|
||||||
|
client_drop_state(c, state);
|
||||||
|
else
|
||||||
|
client_add_state(c, state);
|
||||||
|
}
|
||||||
|
|
||||||
// build a list of visible windows
|
// build a list of visible windows
|
||||||
void windows_visible(stack *s)
|
void windows_visible(stack *s)
|
||||||
{
|
{
|
||||||
@@ -278,6 +329,13 @@ void client_close(client *c)
|
|||||||
void client_position(client *c, int x, int y, int w, int h)
|
void client_position(client *c, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
|
monitor *m = &monitors[c->monitor];
|
||||||
|
|
||||||
|
if (client_state(c, atoms[_NET_WM_STATE_FULLSCREEN]))
|
||||||
|
{
|
||||||
|
XMoveResizeWindow(display, c->window, m->x, m->y, m->w, m->h);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
w -= BORDER*2; h -= BORDER*2;
|
w -= BORDER*2; h -= BORDER*2;
|
||||||
|
|
||||||
@@ -319,8 +377,6 @@ void client_position(client *c, int x, int y, int w, int h)
|
|||||||
if (w < sw) x += (sw-w)/2;
|
if (w < sw) x += (sw-w)/2;
|
||||||
if (h < sh) y += (sh-h)/2;
|
if (h < sh) y += (sh-h)/2;
|
||||||
|
|
||||||
monitor *m = &monitors[c->monitor];
|
|
||||||
|
|
||||||
// bump onto screen
|
// bump onto screen
|
||||||
x = MAX(0, MIN(x, m->x + m->w - w - BORDER*2));
|
x = MAX(0, MIN(x, m->x + m->w - w - BORDER*2));
|
||||||
y = MAX(0, MIN(y, m->y + m->h - h - BORDER*2));
|
y = MAX(0, MIN(y, m->y + m->h - h - BORDER*2));
|
||||||
@@ -556,7 +612,7 @@ void window_listen(Window win)
|
|||||||
void client_review(client *c)
|
void client_review(client *c)
|
||||||
{
|
{
|
||||||
XSetWindowBorder(display, c->window, color_get(c->window == current ? BORDER_FOCUS: BORDER_BLUR));
|
XSetWindowBorder(display, c->window, color_get(c->window == current ? BORDER_FOCUS: BORDER_BLUR));
|
||||||
XSetWindowBorderWidth(display, c->window, BORDER);
|
XSetWindowBorderWidth(display, c->window, client_state(c, atoms[_NET_WM_STATE_FULLSCREEN]) ? 0: BORDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------- event handlers --------
|
// ------- event handlers --------
|
||||||
@@ -734,6 +790,11 @@ void key_press(XKeyEvent *e)
|
|||||||
client_spot(c, c->spot, 1);
|
client_spot(c, c->spot, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ACTION_FULLSCREEN_TOGGLE:
|
||||||
|
client_toggle_state(c, atoms[_NET_WM_STATE_FULLSCREEN]);
|
||||||
|
client_review(c);
|
||||||
|
client_spot(c, c->spot, 1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (act)
|
switch (act)
|
||||||
|
|||||||
@@ -63,13 +63,15 @@ typedef struct {
|
|||||||
monitor monitors[MAX_MONITORS];
|
monitor monitors[MAX_MONITORS];
|
||||||
int nmonitors;
|
int nmonitors;
|
||||||
|
|
||||||
|
#define MAX_NET_WM_STATES 5
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Window window;
|
Window window;
|
||||||
XWindowAttributes attr;
|
XWindowAttributes attr;
|
||||||
XWMHints hints;
|
XWMHints hints;
|
||||||
XSizeHints size;
|
XSizeHints size;
|
||||||
Window transient_for;
|
Window transient_for;
|
||||||
Atom type;
|
Atom type, states[MAX_NET_WM_STATES];
|
||||||
short monitor, spot, visible, trans, manage, input, urgent;
|
short monitor, spot, visible, trans, manage, input, urgent;
|
||||||
} client;
|
} client;
|
||||||
|
|
||||||
@@ -109,6 +111,8 @@ int struts[4] = { 0, 0, 0, 0 };
|
|||||||
X(_NET_WM_WINDOW_TYPE_DIALOG),\
|
X(_NET_WM_WINDOW_TYPE_DIALOG),\
|
||||||
X(_NET_CLIENT_LIST_STACKING),\
|
X(_NET_CLIENT_LIST_STACKING),\
|
||||||
X(_NET_WM_STATE),\
|
X(_NET_WM_STATE),\
|
||||||
|
X(_NET_WM_STATE_FULLSCREEN),\
|
||||||
|
X(_NET_WM_STATE_DEMANDS_ATTENTION),\
|
||||||
X(WM_PROTOCOLS)
|
X(WM_PROTOCOLS)
|
||||||
|
|
||||||
enum { GENERAL_ATOMS(ATOM_ENUM), ATOMS };
|
enum { GENERAL_ATOMS(ATOM_ENUM), ATOMS };
|
||||||
@@ -134,6 +138,7 @@ enum {
|
|||||||
ACTION_MOVE_MONITOR_DEC,
|
ACTION_MOVE_MONITOR_DEC,
|
||||||
ACTION_FOCUS_MONITOR_INC,
|
ACTION_FOCUS_MONITOR_INC,
|
||||||
ACTION_FOCUS_MONITOR_DEC,
|
ACTION_FOCUS_MONITOR_DEC,
|
||||||
|
ACTION_FULLSCREEN_TOGGLE,
|
||||||
ACTIONS
|
ACTIONS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
3
config.h
3
config.h
@@ -63,6 +63,9 @@ binding keys[] = {
|
|||||||
// Gracefully close the current window.
|
// Gracefully close the current window.
|
||||||
{ .mod = Mod4Mask, .key = XK_Escape, .act = ACTION_CLOSE },
|
{ .mod = Mod4Mask, .key = XK_Escape, .act = ACTION_CLOSE },
|
||||||
|
|
||||||
|
// Toggle current window full screen.
|
||||||
|
{ .mod = Mod4Mask, .key = XK_f, .act = ACTION_FULLSCREEN_TOGGLE },
|
||||||
|
|
||||||
// Switch focus between monitors.
|
// Switch focus between monitors.
|
||||||
{ .mod = Mod4Mask, .key = XK_Right, .act = ACTION_FOCUS_MONITOR_INC },
|
{ .mod = Mod4Mask, .key = XK_Right, .act = ACTION_FOCUS_MONITOR_INC },
|
||||||
{ .mod = Mod4Mask, .key = XK_Left, .act = ACTION_FOCUS_MONITOR_DEC },
|
{ .mod = Mod4Mask, .key = XK_Left, .act = ACTION_FOCUS_MONITOR_DEC },
|
||||||
|
|||||||
4
proto.h
4
proto.h
@@ -10,6 +10,10 @@ void window_set_cardinal_prop(Window w, Atom prop, unsigned long *values, int co
|
|||||||
void ewmh_client_list();
|
void ewmh_client_list();
|
||||||
void ewmh_active_window(Window w);
|
void ewmh_active_window(Window w);
|
||||||
client* window_client(Window win);
|
client* window_client(Window win);
|
||||||
|
int client_state(client *c, Atom state);
|
||||||
|
int client_add_state(client *c, Atom state);
|
||||||
|
int client_drop_state(client *c, Atom state);
|
||||||
|
void client_toggle_state(client *c, Atom state);
|
||||||
void windows_visible(stack *s);
|
void windows_visible(stack *s);
|
||||||
int window_message(Window target, Window subject, Atom atom, unsigned long protocol, unsigned long mask);
|
int window_message(Window target, Window subject, Atom atom, unsigned long protocol, unsigned long mask);
|
||||||
void client_free(client *c);
|
void client_free(client *c);
|
||||||
|
|||||||
Reference in New Issue
Block a user