support fullscreen toggle

This commit is contained in:
seanpringle
2012-08-31 18:32:14 +10:00
parent 4c2868cad5
commit 71cf2c073b
5 changed files with 78 additions and 5 deletions

View File

@@ -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.

View File

@@ -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)

View File

@@ -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
}; };

View File

@@ -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 },

View File

@@ -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);