Add client frame
This commit is contained in:
parent
6215f23f86
commit
67cb8cd5ba
@ -22,6 +22,7 @@
|
||||
#define barwin_refresh(b) XCopyArea(W->dpy, b->dr, b->win, W->gc, 0, 0, b->geo.w, b->geo.h, 0, 0)
|
||||
#define barwin_map(b) XMapWindow(W->dpy, b->win);
|
||||
#define barwin_unmap(b) XUnmapWindow(W->dpy, b->win);
|
||||
#define barwin_move(b, x, y) XMoveWindow(W->dpy, b->win, x, y);
|
||||
|
||||
struct barwin* barwin_new(Window parent, int x, int y, int w, int h, Color fg, Color bg, bool entermask);
|
||||
void barwin_remove(struct barwin *b);
|
||||
|
||||
197
src/client.c
197
src/client.c
@ -12,8 +12,10 @@
|
||||
#include "barwin.h"
|
||||
#include "ewmh.h"
|
||||
#include "layout.h"
|
||||
#include "barwin.h"
|
||||
#include "draw.h"
|
||||
|
||||
#define CCOL(c) (c == c->tag->sel ? &c->scol : &c->ncol)
|
||||
#define CLIENT_MOUSE_MOD Mod1Mask
|
||||
|
||||
#define CLIENT_RESIZE_DIR(D) \
|
||||
@ -87,10 +89,10 @@ client_configure(struct client *c)
|
||||
.type = ConfigureNotify,
|
||||
.event = c->win,
|
||||
.window = c->win,
|
||||
.x = c->geo.x,
|
||||
.y = c->geo.y,
|
||||
.width = c->geo.w,
|
||||
.height = c->geo.h,
|
||||
.x = c->rgeo.x + c->border,
|
||||
.y = c->rgeo.y + c->tbarw,
|
||||
.width = c->wgeo.w,
|
||||
.height = c->wgeo.h,
|
||||
.above = None,
|
||||
.border_width = 0,
|
||||
.override_redirect = 0
|
||||
@ -111,6 +113,17 @@ client_gb_win(Window w)
|
||||
return c;
|
||||
}
|
||||
|
||||
struct client*
|
||||
client_gb_frame(Window w)
|
||||
{
|
||||
struct client *c = SLIST_FIRST(&W->h.client);
|
||||
|
||||
while(c && c->frame != w)
|
||||
c = SLIST_NEXT(c, next);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
struct client*
|
||||
client_gb_pos(struct tag *t, int x, int y)
|
||||
{
|
||||
@ -164,8 +177,8 @@ client_swap2(struct client *c1, struct client *c2)
|
||||
return;
|
||||
|
||||
/* are swapped geos compatible? */
|
||||
if(client_winsize(c1, &c2->geo, &c1->wgeo)
|
||||
|| client_winsize(c2, &c1->geo, &c2->wgeo))
|
||||
if(client_winsize(c1, &c2->geo)
|
||||
|| client_winsize(c2, &c1->geo))
|
||||
return;
|
||||
|
||||
if(c1->screen != c2->screen)
|
||||
@ -199,6 +212,8 @@ _swap_get(struct client *c, enum position p)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define _REV_SBORDER() \
|
||||
draw_reversed_rect(W->root, W->rgc, &c2->geo);
|
||||
void
|
||||
client_swap(struct client *c, enum position p)
|
||||
{
|
||||
@ -207,13 +222,6 @@ client_swap(struct client *c, enum position p)
|
||||
bool b = true;
|
||||
XEvent ev;
|
||||
KeySym keysym;
|
||||
GC rgc;
|
||||
XGCValues xgc =
|
||||
{
|
||||
.function = GXinvert,
|
||||
.subwindow_mode = IncludeInferiors,
|
||||
.line_width = THEME_DEFAULT->client_border_width
|
||||
};
|
||||
|
||||
c2 = _swap_get(c, p);
|
||||
|
||||
@ -226,9 +234,7 @@ client_swap(struct client *c, enum position p)
|
||||
*/
|
||||
|
||||
XGrabKeyboard(W->dpy, W->root, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
rgc = XCreateGC(W->dpy, c->tag->frame, GCFunction | GCSubwindowMode | GCLineWidth, &xgc);
|
||||
|
||||
draw_reversed_rect(c->tag->frame, rgc, c2->geo);
|
||||
_REV_SBORDER();
|
||||
|
||||
do
|
||||
{
|
||||
@ -239,7 +245,7 @@ client_swap(struct client *c, enum position p)
|
||||
XKeyPressedEvent *ke = &ev.xkey;
|
||||
keysym = XKeycodeToKeysym(W->dpy, (KeyCode)ke->keycode, 0);
|
||||
|
||||
draw_reversed_rect(c->tag->frame, rgc, c2->geo);
|
||||
_REV_SBORDER();
|
||||
|
||||
SLIST_FOREACH(k, &W->h.keybind, next)
|
||||
if(k->keysym == keysym && KEYPRESS_MASK(k->mod) == KEYPRESS_MASK(ke->state)
|
||||
@ -260,7 +266,7 @@ client_swap(struct client *c, enum position p)
|
||||
}
|
||||
}
|
||||
|
||||
draw_reversed_rect(c->tag->frame, rgc, c2->geo);
|
||||
_REV_SBORDER();
|
||||
|
||||
/* Gtfo of this loop */
|
||||
if(keysym == XK_Return)
|
||||
@ -277,12 +283,11 @@ client_swap(struct client *c, enum position p)
|
||||
|
||||
} while(ev.type != KeyPress);
|
||||
|
||||
draw_reversed_rect(c->tag->frame, rgc, c2->geo);
|
||||
_REV_SBORDER();
|
||||
|
||||
if(b)
|
||||
client_swap2(c, c2);
|
||||
|
||||
XFreeGC(W->dpy, rgc);
|
||||
XUngrabKeyboard(W->dpy, CurrentTime);
|
||||
}
|
||||
|
||||
@ -314,33 +319,47 @@ client_grabbuttons(struct client *c, bool focused)
|
||||
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
|
||||
}
|
||||
|
||||
static inline void
|
||||
client_draw_bord(struct client *c)
|
||||
static void
|
||||
client_frame_update(struct client *c, struct colpair *cp)
|
||||
{
|
||||
struct geo ge = { 0, 0, c->screen->ugeo.w, c->screen->ugeo.h };
|
||||
XSetWindowBackground(W->dpy, c->frame, cp->bg);
|
||||
XClearWindow(W->dpy, c->frame);
|
||||
|
||||
draw_rect(c->tag->frame, ge, THEME_DEFAULT->client_n.bg);
|
||||
if(c->titlebar && c->title)
|
||||
{
|
||||
int w = draw_textw(THEME_DEFAULT, c->title);
|
||||
|
||||
/* Selected client's border */
|
||||
if(W->client)
|
||||
draw_rect(W->client->tag->frame, W->client->tag->sel->geo, THEME_DEFAULT->client_s.bg);
|
||||
c->titlebar->fg = cp->fg;
|
||||
c->titlebar->bg = cp->bg;
|
||||
|
||||
barwin_move(c->titlebar, (c->geo.w >> 1) - (w >> 1) - PAD, 0);
|
||||
barwin_resize(c->titlebar, w + (PAD << 1), c->tbarw);
|
||||
barwin_refresh_color(c->titlebar);
|
||||
|
||||
draw_text(c->titlebar->dr, THEME_DEFAULT,
|
||||
PAD, TEXTY(THEME_DEFAULT, c->tbarw), cp->fg,
|
||||
c->title);
|
||||
|
||||
barwin_refresh(c->titlebar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
client_focus(struct client *c)
|
||||
{
|
||||
/* Unfocus selected */
|
||||
if(W->client && W->client != c)
|
||||
{
|
||||
client_grabbuttons(W->client, false);
|
||||
client_frame_update(W->client, &W->client->ncol);
|
||||
}
|
||||
|
||||
/* Focus c */
|
||||
if((W->client = c))
|
||||
{
|
||||
c->tag->sel = c;
|
||||
|
||||
client_draw_bord(c);
|
||||
client_grabbuttons(c, true);
|
||||
client_frame_update(c, &c->scol);
|
||||
|
||||
XSetInputFocus(W->dpy, c->win, RevertToPointerRoot, CurrentTime);
|
||||
}
|
||||
@ -370,6 +389,8 @@ client_get_name(struct client *c)
|
||||
/* Still no title... */
|
||||
if(!c->title)
|
||||
XFetchName(W->dpy, c->win, &(c->title));
|
||||
|
||||
client_frame_update(c, CCOL(c));
|
||||
}
|
||||
|
||||
/** Close a client
|
||||
@ -477,6 +498,33 @@ client_get_sizeh(struct client *c)
|
||||
c->flags |= CLIENT_HINT_FLAG;
|
||||
}
|
||||
|
||||
static void
|
||||
client_frame_new(struct client *c)
|
||||
{
|
||||
XSetWindowAttributes at =
|
||||
{
|
||||
.background_pixel = c->ncol.bg,
|
||||
.override_redirect = true,
|
||||
.background_pixmap = ParentRelative,
|
||||
.event_mask = BARWIN_MASK | BARWIN_ENTERMASK
|
||||
};
|
||||
|
||||
c->frame = XCreateWindow(W->dpy, W->root,
|
||||
c->geo.x, c->geo.y,
|
||||
c->geo.w, c->geo.h,
|
||||
0, CopyFromParent,
|
||||
InputOutput,
|
||||
CopyFromParent,
|
||||
(CWOverrideRedirect | CWBackPixmap
|
||||
| CWBackPixel | CWEventMask), &at);
|
||||
|
||||
if(c->tbarw > c->border)
|
||||
c->titlebar = barwin_new(c->frame, 0, 0, 1, c->tbarw,
|
||||
c->ncol.fg, c->ncol.bg, true);
|
||||
|
||||
XReparentWindow(W->dpy, c->win, c->frame, c->border, c->tbarw);
|
||||
}
|
||||
|
||||
struct client*
|
||||
client_new(Window w, XWindowAttributes *wa)
|
||||
{
|
||||
@ -493,7 +541,22 @@ client_new(Window w, XWindowAttributes *wa)
|
||||
c->geo.y = wa->y;
|
||||
c->geo.w = wa->width;
|
||||
c->geo.h = wa->height;
|
||||
c->tgeo = c->wgeo = c->owgeo = c->geo;
|
||||
c->tgeo = c->wgeo = c->rgeo = c->geo;
|
||||
|
||||
/*
|
||||
* Conf option set per client, for possibility
|
||||
* to config only one client
|
||||
*/
|
||||
c->border = THEME_DEFAULT->client_border_width;
|
||||
if(!(c->tbarw = THEME_DEFAULT->client_titlebar_width))
|
||||
c->tbarw = c->border;
|
||||
|
||||
c->ncol.fg = THEME_DEFAULT->client_n.fg;
|
||||
c->ncol.bg = THEME_DEFAULT->client_n.bg;
|
||||
c->scol.fg = THEME_DEFAULT->client_s.fg;
|
||||
c->scol.bg = THEME_DEFAULT->client_s.bg;
|
||||
|
||||
client_frame_new(c);
|
||||
|
||||
/* Set tag */
|
||||
client_get_sizeh(c);
|
||||
@ -508,7 +571,10 @@ client_new(Window w, XWindowAttributes *wa)
|
||||
SLIST_INSERT_HEAD(&W->h.client, c, next);
|
||||
|
||||
/* Map */
|
||||
WIN_STATE(w, Map);
|
||||
WIN_STATE(c->frame, Map);
|
||||
if(c->titlebar)
|
||||
barwin_map(c->titlebar);
|
||||
|
||||
ewmh_set_wm_state(w, NormalState);
|
||||
|
||||
client_get_name(c);
|
||||
@ -555,32 +621,29 @@ client_geo_hints(struct geo *g, int *s)
|
||||
}
|
||||
|
||||
bool
|
||||
client_winsize(struct client *c, struct geo *g, struct geo *ret)
|
||||
client_winsize(struct client *c, struct geo *g)
|
||||
{
|
||||
int ow, bord = THEME_DEFAULT->client_border_width;
|
||||
|
||||
c->owgeo = c->wgeo;
|
||||
int ow;
|
||||
struct geo og = c->wgeo;
|
||||
|
||||
/* Window geo */
|
||||
ret->x = g->x + bord;
|
||||
ret->y = g->y + bord;
|
||||
ret->h = g->h - (bord << 1);
|
||||
ret->w = ow = g->w - (bord << 1);
|
||||
c->wgeo.x = c->border;
|
||||
c->wgeo.y = c->tbarw;
|
||||
c->wgeo.h = g->h - (c->border + c->tbarw);
|
||||
c->wgeo.w = ow = g->w - (c->border << 1);
|
||||
|
||||
client_geo_hints(ret, (int*)c->sizeh);
|
||||
client_geo_hints(&c->wgeo, (int*)c->sizeh);
|
||||
|
||||
/* Check possible problem for tile integration */
|
||||
if(g->w < c->sizeh[MINW] || g->h < c->sizeh[MINH]
|
||||
|| g->x < 0 || g->y < 0
|
||||
|| ret->x < g->x || ret->y < g->y
|
||||
|| ret->h > g->h || ret->w > g->w)
|
||||
|| c->wgeo.h > g->h || c->wgeo.w > g->w)
|
||||
{
|
||||
*ret = c->wgeo;
|
||||
c->wgeo = og;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Balance position with new size */
|
||||
ret->x += (ow - ret->w) >> 1;
|
||||
c->wgeo.x += (ow - c->wgeo.w) >> 1;
|
||||
|
||||
c->flags |= CLIENT_DID_WINSIZE;
|
||||
|
||||
@ -590,11 +653,24 @@ client_winsize(struct client *c, struct geo *g, struct geo *ret)
|
||||
void
|
||||
client_moveresize(struct client *c, struct geo *g)
|
||||
{
|
||||
c->tgeo = c->geo = *g;
|
||||
c->tgeo = c->rgeo = c->geo = *g;
|
||||
|
||||
if(!(c->flags & CLIENT_DID_WINSIZE))
|
||||
if(client_winsize(c, g, &c->wgeo))
|
||||
return;
|
||||
if(client_winsize(c, g))
|
||||
{
|
||||
/* TODO
|
||||
* Window required size not compatible
|
||||
* with frame window size in tile mode
|
||||
*/
|
||||
}
|
||||
|
||||
/* Real geo regarding full root size */
|
||||
c->rgeo.x += c->screen->ugeo.x;
|
||||
c->rgeo.y += c->screen->ugeo.y;
|
||||
|
||||
XMoveResizeWindow(W->dpy, c->frame,
|
||||
c->rgeo.x, c->rgeo.y,
|
||||
c->rgeo.w, c->rgeo.h);
|
||||
|
||||
XMoveResizeWindow(W->dpy, c->win,
|
||||
c->wgeo.x, c->wgeo.y,
|
||||
@ -602,18 +678,15 @@ client_moveresize(struct client *c, struct geo *g)
|
||||
|
||||
c->flags &= ~CLIENT_DID_WINSIZE;
|
||||
|
||||
client_draw_bord(c);
|
||||
client_frame_update(c, CCOL(c));
|
||||
client_configure(c);
|
||||
}
|
||||
|
||||
void
|
||||
client_maximize(struct client *c)
|
||||
{
|
||||
c->geo = c->tag->screen->ugeo;
|
||||
|
||||
c->geo.x = c->geo.y = 0; /* Frame x/y, not screen geo */
|
||||
c->geo.w = c->tag->screen->ugeo.w;
|
||||
c->geo.h = c->tag->screen->ugeo.h;
|
||||
c->geo = c->screen->ugeo;
|
||||
c->geo.x = c->geo.y = 0;
|
||||
|
||||
client_moveresize(c, &c->geo);
|
||||
|
||||
@ -684,7 +757,7 @@ _fac_resize(struct client *c, enum position p, int fac)
|
||||
* clients in linked list.
|
||||
*/
|
||||
SLIST_FOREACH(gc, &c->tag->clients, tnext)
|
||||
if(client_winsize(gc, &gc->tgeo, &gc->wgeo))
|
||||
if(client_winsize(gc, &gc->tgeo))
|
||||
{
|
||||
/*
|
||||
* Reverse back the flag and the window geo
|
||||
@ -702,7 +775,7 @@ _fac_resize(struct client *c, enum position p, int fac)
|
||||
|
||||
#define _REV_BORDER() \
|
||||
SLIST_FOREACH(gc, &c->tag->clients, tnext) \
|
||||
draw_reversed_rect(c->tag->frame, rgc, gc->tgeo);
|
||||
draw_reversed_rect(W->root, W->rgc, &gc->tgeo);
|
||||
void
|
||||
client_fac_resize(struct client *c, enum position p, int fac)
|
||||
{
|
||||
@ -711,13 +784,6 @@ client_fac_resize(struct client *c, enum position p, int fac)
|
||||
bool b = true;
|
||||
XEvent ev;
|
||||
KeySym keysym;
|
||||
GC rgc;
|
||||
XGCValues xgc =
|
||||
{
|
||||
.function = GXinvert,
|
||||
.subwindow_mode = IncludeInferiors,
|
||||
.line_width = THEME_DEFAULT->client_border_width
|
||||
};
|
||||
|
||||
/* Do it once before */
|
||||
_fac_resize(c, p, fac);
|
||||
@ -729,7 +795,6 @@ client_fac_resize(struct client *c, enum position p, int fac)
|
||||
|
||||
XGrabServer(W->dpy);
|
||||
XGrabKeyboard(W->dpy, W->root, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
rgc = XCreateGC(W->dpy, c->tag->frame, GCFunction | GCSubwindowMode | GCLineWidth, &xgc);
|
||||
|
||||
_REV_BORDER();
|
||||
|
||||
@ -800,7 +865,6 @@ client_fac_resize(struct client *c, enum position p, int fac)
|
||||
}
|
||||
}
|
||||
|
||||
XFreeGC(W->dpy, rgc);
|
||||
XUngrabServer(W->dpy);
|
||||
XUngrabKeyboard(W->dpy, CurrentTime);
|
||||
}
|
||||
@ -811,6 +875,7 @@ client_remove(struct client *c)
|
||||
XGrabServer(W->dpy);
|
||||
XSetErrorHandler(wmfs_error_handler_dummy);
|
||||
XReparentWindow(W->dpy, c->win, W->root, c->geo.x, c->geo.y);
|
||||
XDestroyWindow(W->dpy, c->frame);
|
||||
|
||||
/* Remove from global client list */
|
||||
SLIST_REMOVE(&W->h.client, c, client, next);
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
inline void client_configure(struct client *c);
|
||||
struct client *client_gb_win(Window w);
|
||||
struct client *client_gb_frame(Window w);
|
||||
struct client *client_gb_pos(struct tag *t, int x, int y);
|
||||
struct client *client_next_with_pos(struct client *bc, enum position p);
|
||||
void client_swap2(struct client *c1, struct client *c2);
|
||||
@ -20,7 +21,7 @@ void client_get_name(struct client *c);
|
||||
void client_close(struct client *c);
|
||||
void uicb_client_close(Uicb cmd);
|
||||
struct client *client_new(Window w, XWindowAttributes *wa);
|
||||
bool client_winsize(struct client *c, struct geo *geo, struct geo *ret);
|
||||
bool client_winsize(struct client *c, struct geo *geo);
|
||||
void client_moveresize(struct client *c, struct geo *g);
|
||||
void client_maximize(struct client *c);
|
||||
void client_fac_resize(struct client *c, enum position p, int fac);
|
||||
|
||||
10
src/draw.h
10
src/draw.h
@ -34,12 +34,16 @@ draw_rect(Drawable d, struct geo g, Color bg)
|
||||
* For client use
|
||||
*/
|
||||
static inline void
|
||||
draw_reversed_rect(Drawable dr, GC gc, struct geo g)
|
||||
draw_reversed_rect(Drawable dr, GC gc, struct geo *g)
|
||||
{
|
||||
struct geo *ug = &W->screen->ugeo;
|
||||
int i = THEME_DEFAULT->client_border_width;
|
||||
|
||||
XDrawRectangle(W->dpy, dr, gc, g.x + i, g.y + i,
|
||||
g.w - (i << 1), g.h - (i << 1));
|
||||
XDrawRectangle(W->dpy, dr, gc,
|
||||
ug->x + g->x + i,
|
||||
ug->y + g->y + i,
|
||||
g->w - (i << 1),
|
||||
g->h - (i << 1));
|
||||
}
|
||||
|
||||
static inline unsigned short
|
||||
|
||||
@ -46,8 +46,9 @@ event_enternotify(XEvent *e)
|
||||
&& ev->window != W->root)
|
||||
return;
|
||||
|
||||
if((c = client_gb_win(ev->window)))
|
||||
{
|
||||
if((c = client_gb_win(ev->window))
|
||||
|| (c = client_gb_frame(ev->window)))
|
||||
{
|
||||
if(c->flags & CLIENT_IGNORE_ENTER)
|
||||
c->flags ^= CLIENT_IGNORE_ENTER;
|
||||
else
|
||||
@ -193,14 +194,13 @@ event_motionnotify(XEvent *e)
|
||||
{
|
||||
XMotionEvent *ev = &e->xmotion;
|
||||
struct client *c;
|
||||
struct tag *t = W->screen->seltag;
|
||||
|
||||
/*
|
||||
* Check client window and tag frame to get focused
|
||||
* window with mouse motion
|
||||
*/
|
||||
if((c = client_gb_win(ev->subwindow))
|
||||
|| (ev->window == t->frame && ((c = client_gb_pos(t, ev->x, ev->y)))))
|
||||
|| (c = client_gb_frame(ev->subwindow)))
|
||||
if(c != c->tag->sel)
|
||||
client_focus(c);
|
||||
}
|
||||
|
||||
@ -53,8 +53,6 @@ infobar_placement(struct infobar *i, enum barpos p)
|
||||
return false;
|
||||
}
|
||||
|
||||
tag_update_frame_geo(i->screen);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
19
src/layout.c
19
src/layout.c
@ -46,7 +46,7 @@ static void
|
||||
layout_apply_set(struct tag *t, struct layout_set *l)
|
||||
{
|
||||
struct geo_list *g;
|
||||
struct client *c, cc;
|
||||
struct client *c;
|
||||
int nc = 1;
|
||||
|
||||
SLIST_FOREACH(c, &t->clients, tnext)
|
||||
@ -105,7 +105,7 @@ layout_free_set(struct tag *t)
|
||||
|
||||
#define _REV_BORDER() \
|
||||
SLIST_FOREACH(g, &l->geos, next) \
|
||||
draw_reversed_rect(t->frame, rgc, g->geo);
|
||||
draw_reversed_rect(W->root, W->rgc, &g->geo);
|
||||
static void
|
||||
_historic_set(struct tag *t, bool prev)
|
||||
{
|
||||
@ -115,13 +115,6 @@ _historic_set(struct tag *t, bool prev)
|
||||
bool b = true;
|
||||
XEvent ev;
|
||||
KeySym keysym;
|
||||
GC rgc;
|
||||
XGCValues xgc =
|
||||
{
|
||||
.function = GXinvert,
|
||||
.subwindow_mode = IncludeInferiors,
|
||||
.line_width = THEME_DEFAULT->client_border_width
|
||||
};
|
||||
|
||||
if(TAILQ_EMPTY(&t->sets))
|
||||
return;
|
||||
@ -142,7 +135,6 @@ _historic_set(struct tag *t, bool prev)
|
||||
*/
|
||||
|
||||
XGrabKeyboard(W->dpy, W->root, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
rgc = XCreateGC(W->dpy, t->frame, GCFunction | GCSubwindowMode | GCLineWidth, &xgc);
|
||||
|
||||
_REV_BORDER();
|
||||
|
||||
@ -203,7 +195,6 @@ _historic_set(struct tag *t, bool prev)
|
||||
if(b)
|
||||
layout_apply_set(t, l);
|
||||
|
||||
XFreeGC(W->dpy, rgc);
|
||||
XUngrabServer(W->dpy);
|
||||
XUngrabKeyboard(W->dpy, CurrentTime);
|
||||
}
|
||||
@ -339,7 +330,6 @@ layout_split_arrange_closed(struct client *ghost)
|
||||
_ARRANGE_SINGLE_PARENT(Top);
|
||||
_ARRANGE_SINGLE_PARENT(Bottom);
|
||||
|
||||
|
||||
/* Check row parents for full resize
|
||||
* Example case:
|
||||
* ___________ ___________
|
||||
@ -460,16 +450,17 @@ static void
|
||||
layout_rotate(struct tag *t, void (*pfunc)(struct geo*, struct geo*, struct geo*))
|
||||
{
|
||||
struct client *c;
|
||||
struct geo g;
|
||||
struct geo g, *ug = &t->screen->ugeo;
|
||||
float f1 = (float)t->screen->ugeo.w / (float)t->screen->ugeo.h;
|
||||
float f2 = 1 / f1;
|
||||
|
||||
SLIST_FOREACH(c, &t->clients, tnext)
|
||||
{
|
||||
pfunc(&g, &t->screen->ugeo, &c->geo);
|
||||
pfunc(&g, ug, &c->geo);
|
||||
|
||||
g.x *= f1;
|
||||
g.y *= f2;
|
||||
|
||||
g.w = c->geo.h * f1;
|
||||
g.h = c->geo.w * f2;
|
||||
|
||||
|
||||
45
src/tag.c
45
src/tag.c
@ -18,13 +18,6 @@ struct tag*
|
||||
tag_new(struct screen *s, char *name)
|
||||
{
|
||||
struct tag *t;
|
||||
XSetWindowAttributes at =
|
||||
{
|
||||
.background_pixel = THEME_DEFAULT->frame_bg,
|
||||
.override_redirect = true,
|
||||
.background_pixmap = ParentRelative,
|
||||
.event_mask = BARWIN_MASK
|
||||
};
|
||||
|
||||
t = xcalloc(1, sizeof(struct tag));
|
||||
|
||||
@ -33,17 +26,6 @@ tag_new(struct screen *s, char *name)
|
||||
t->flags = 0;
|
||||
t->sel = NULL;
|
||||
|
||||
/* Frame window */
|
||||
t->frame = XCreateWindow(W->dpy, W->root,
|
||||
s->ugeo.x, s->ugeo.y,
|
||||
s->ugeo.w, s->ugeo.h,
|
||||
0, CopyFromParent,
|
||||
InputOutput,
|
||||
CopyFromParent,
|
||||
(CWOverrideRedirect | CWBackPixmap
|
||||
| CWBackPixel | CWEventMask),
|
||||
&at);
|
||||
|
||||
SLIST_INIT(&t->clients);
|
||||
TAILQ_INIT(&t->sets);
|
||||
|
||||
@ -58,9 +40,11 @@ tag_screen(struct screen *s, struct tag *t)
|
||||
struct client *c;
|
||||
|
||||
/* Unmap previous tag's frame */
|
||||
WIN_STATE(s->seltag->frame, Unmap);
|
||||
SLIST_FOREACH(c, &s->seltag->clients, tnext)
|
||||
{
|
||||
WIN_STATE(c->frame, Unmap);
|
||||
ewmh_set_wm_state(c->win, IconicState);
|
||||
}
|
||||
|
||||
/*
|
||||
* Map selected tag's frame, only if there is
|
||||
@ -68,9 +52,11 @@ tag_screen(struct screen *s, struct tag *t)
|
||||
*/
|
||||
if(!SLIST_EMPTY(&t->clients))
|
||||
{
|
||||
WIN_STATE(t->frame, Map);
|
||||
SLIST_FOREACH(c, &t->clients, tnext)
|
||||
{
|
||||
WIN_STATE(c->frame, Map);
|
||||
ewmh_set_wm_state(c->win, NormalState);
|
||||
}
|
||||
|
||||
client_focus(t->sel);
|
||||
}
|
||||
@ -98,24 +84,9 @@ tag_client(struct tag *t, struct client *c)
|
||||
client_focus(client_next(c));
|
||||
}
|
||||
|
||||
/*
|
||||
* Case of client removing: umap frame if empty
|
||||
*/
|
||||
/* Client remove */
|
||||
if(!t)
|
||||
{
|
||||
/* Unmap frame if tag is now empty */
|
||||
if(SLIST_EMPTY(&c->tag->clients))
|
||||
WIN_STATE(c->tag->frame, Unmap);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reparent client win in frame win */
|
||||
XReparentWindow(W->dpy, c->win, t->frame, 0, 0);
|
||||
|
||||
/* Map frame if tag was empty */
|
||||
if(SLIST_EMPTY(&t->clients))
|
||||
WIN_STATE(t->frame, Map);
|
||||
|
||||
c->tag = t;
|
||||
|
||||
@ -184,8 +155,6 @@ tag_remove(struct tag *t)
|
||||
{
|
||||
free(t->name);
|
||||
|
||||
XDestroyWindow(W->dpy, t->frame);
|
||||
|
||||
layout_free_set(t);
|
||||
|
||||
free(t);
|
||||
|
||||
18
src/tag.h
18
src/tag.h
@ -17,22 +17,4 @@ void uicb_tag_set_with_name(Uicb cmd);
|
||||
void uicb_tag_next(Uicb cmd);
|
||||
void uicb_tag_prev(Uicb cmd);
|
||||
|
||||
/*
|
||||
* Update frames size with screen usable geo
|
||||
*/
|
||||
static inline void
|
||||
tag_update_frame_geo(struct screen *s)
|
||||
{
|
||||
struct tag *t;
|
||||
|
||||
TAILQ_FOREACH(t, &s->tags, next)
|
||||
XMoveResizeWindow(W->dpy,
|
||||
t->frame,
|
||||
s->ugeo.x,
|
||||
s->ugeo.y,
|
||||
s->ugeo.w,
|
||||
s->ugeo.h);
|
||||
}
|
||||
|
||||
|
||||
#endif /* TAG_H */
|
||||
|
||||
10
src/wmfs.c
10
src/wmfs.c
@ -101,6 +101,13 @@ wmfs_init_font(char *font, struct theme *t)
|
||||
static void
|
||||
wmfs_xinit(void)
|
||||
{
|
||||
XGCValues xgc =
|
||||
{
|
||||
.function = GXinvert,
|
||||
.subwindow_mode = IncludeInferiors,
|
||||
.line_width = 1
|
||||
};
|
||||
|
||||
XSetWindowAttributes at =
|
||||
{
|
||||
.event_mask = (KeyMask | ButtonMask | MouseMask
|
||||
@ -131,6 +138,8 @@ wmfs_xinit(void)
|
||||
*/
|
||||
W->root = RootWindow(W->dpy, W->xscreen);
|
||||
XChangeWindowAttributes(W->dpy, W->root, CWEventMask | CWCursor, &at);
|
||||
W->rgc = XCreateGC(W->dpy, W->root, GCFunction | GCSubwindowMode | GCLineWidth, &xgc);
|
||||
|
||||
|
||||
/*
|
||||
* Locale (font encode)
|
||||
@ -261,6 +270,7 @@ wmfs_quit(void)
|
||||
*/
|
||||
screen_free();
|
||||
|
||||
XFreeGC(W->dpy, W->rgc);
|
||||
XCloseDisplay(W->dpy);
|
||||
|
||||
/* Conf stuffs */
|
||||
|
||||
19
src/wmfs.h
19
src/wmfs.h
@ -75,6 +75,11 @@ struct geo_list
|
||||
SLIST_ENTRY(geo_list) next;
|
||||
};
|
||||
|
||||
struct colpair
|
||||
{
|
||||
Color fg, bg;
|
||||
};
|
||||
|
||||
struct barwin
|
||||
{
|
||||
struct geo geo;
|
||||
@ -128,7 +133,6 @@ struct tag
|
||||
struct client *prevsel;
|
||||
char *name;
|
||||
Flags flags;
|
||||
Window frame;
|
||||
SLIST_HEAD(, client) clients;
|
||||
TAILQ_HEAD(ssub, layout_set) sets;
|
||||
TAILQ_ENTRY(tag) next;
|
||||
@ -139,14 +143,16 @@ struct client
|
||||
struct tag *tag;
|
||||
struct screen *screen;
|
||||
struct barwin *titlebar;
|
||||
struct geo geo, tgeo, wgeo, owgeo;
|
||||
struct geo geo, wgeo, tgeo, rgeo;
|
||||
struct colpair ncol, scol;
|
||||
int sizeh[SHLAST];
|
||||
char *title;
|
||||
int border, tbarw;
|
||||
#define CLIENT_HINT_FLAG 0x01
|
||||
#define CLIENT_IGNORE_ENTER 0x02
|
||||
#define CLIENT_DID_WINSIZE 0x04
|
||||
Flags flags;
|
||||
Window win;
|
||||
Window win, frame;
|
||||
SLIST_ENTRY(client) next; /* Global list */
|
||||
SLIST_ENTRY(client) tnext; /* struct tag list */
|
||||
};
|
||||
@ -177,11 +183,6 @@ struct mousebind
|
||||
SLIST_ENTRY(mousebind) next;
|
||||
};
|
||||
|
||||
struct colpair
|
||||
{
|
||||
Color fg, bg;
|
||||
};
|
||||
|
||||
struct theme
|
||||
{
|
||||
char *name;
|
||||
@ -218,7 +219,7 @@ struct wmfs
|
||||
Window root;
|
||||
int xscreen, xdepth;
|
||||
Flags numlockmask;
|
||||
GC gc;
|
||||
GC gc, rgc;
|
||||
Atom *net_atom;
|
||||
bool running;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user