minimal tab support
This commit is contained in:
parent
fa98171d0b
commit
14ea2dc0ae
2
Makefile
2
Makefile
|
@ -3,7 +3,7 @@
|
|||
|
||||
include config.mk
|
||||
|
||||
SRC = client.c draw.c event.c layout.c awesome.c tag.c util.c config.c screen.c statusbar.c uicb.c
|
||||
SRC = client.c draw.c event.c layout.c awesome.c tag.c util.c config.c screen.c statusbar.c uicb.c tab.c
|
||||
OBJ = ${SRC:.c=.o} ${LAYOUTS:.c=.o}
|
||||
|
||||
all: options awesome
|
||||
|
|
25
awesomerc
25
awesomerc
|
@ -18,6 +18,7 @@ colors
|
|||
focus_border = "#6666ff"
|
||||
focus_bg = "#6666ff"
|
||||
focus_fg = "#ffffff"
|
||||
tab_border = "#ff0000"
|
||||
}
|
||||
|
||||
statusbar
|
||||
|
@ -559,4 +560,28 @@ keys
|
|||
command = "toggletag"
|
||||
arg = "9"
|
||||
}
|
||||
key
|
||||
{
|
||||
modkey = {"Mod4"}
|
||||
key = "u"
|
||||
command = "viewprevtab"
|
||||
}
|
||||
key
|
||||
{
|
||||
modkey = {"Mod4"}
|
||||
key = "i"
|
||||
command = "viewnexttab"
|
||||
}
|
||||
key
|
||||
{
|
||||
modkey = {"Mod4", "Control"}
|
||||
key = "u"
|
||||
command = "untab"
|
||||
}
|
||||
key
|
||||
{
|
||||
modkey = {"Mod4", "Control"}
|
||||
key = "i"
|
||||
command = "tab"
|
||||
}
|
||||
}
|
||||
|
|
6
client.c
6
client.c
|
@ -320,7 +320,10 @@ focus(Display *disp, Client * c, Bool selscreen, awesome_config *awesomeconf)
|
|||
drawstatusbar(disp, awesomeconf);
|
||||
if(*awesomeconf->client_sel)
|
||||
{
|
||||
XSetWindowBorder(awesomeconf->display, (*awesomeconf->client_sel)->win, awesomeconf->colors_selected[ColBorder].pixel);
|
||||
if((*awesomeconf->client_sel)->tab.next || (*awesomeconf->client_sel)->tab.prev)
|
||||
XSetWindowBorder(awesomeconf->display, (*awesomeconf->client_sel)->win, awesomeconf->colors_tab[ColBorder].pixel);
|
||||
else
|
||||
XSetWindowBorder(awesomeconf->display, (*awesomeconf->client_sel)->win, awesomeconf->colors_selected[ColBorder].pixel);
|
||||
XSetInputFocus(awesomeconf->display, (*awesomeconf->client_sel)->win, RevertToPointerRoot, CurrentTime);
|
||||
for(c = *awesomeconf->clients; c; c = c->next)
|
||||
if(c != *awesomeconf->client_sel)
|
||||
|
@ -388,6 +391,7 @@ manage(Display *disp, Window w, XWindowAttributes *wa, awesome_config *awesomeco
|
|||
c->oldborder = wa->border_width;
|
||||
c->display = disp;
|
||||
c->phys_screen = get_phys_screen(c->display, c->screen);
|
||||
c->tab.isvisible = True;
|
||||
screen_info = get_screen_info(c->display, c->screen, NULL);
|
||||
if(c->w == screen_info[c->screen].width && c->h == screen_info[c->screen].height)
|
||||
{
|
||||
|
|
8
config.c
8
config.c
|
@ -33,6 +33,7 @@
|
|||
#include "tag.h"
|
||||
#include "statusbar.h"
|
||||
#include "layout.h"
|
||||
#include "tab.h"
|
||||
#include "layouts/tile.h"
|
||||
#include "layouts/floating.h"
|
||||
#include "layouts/max.h"
|
||||
|
@ -91,6 +92,11 @@ const NameFuncLink UicbList[] = {
|
|||
/* statusbar.c */
|
||||
{"togglebar", uicb_togglebar},
|
||||
{"setstatustext", uicb_setstatustext},
|
||||
/* tab.c */
|
||||
{"tab", uicb_tab},
|
||||
{"untab", uicb_untab},
|
||||
{"viewnexttab", uicb_viewnexttab},
|
||||
{"viewprevtab", uicb_viewprevtab},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -161,6 +167,7 @@ parse_config(Display * disp, int scr,const char *confpatharg, awesome_config *aw
|
|||
CFG_STR((char *) "focus_border", (char *) "#6666ff", CFGF_NONE),
|
||||
CFG_STR((char *) "focus_bg", (char *) "#6666ff", CFGF_NONE),
|
||||
CFG_STR((char *) "focus_fg", (char *) "#ffffff", CFGF_NONE),
|
||||
CFG_STR((char *) "tab_border", (char *) "#ff0000", CFGF_NONE),
|
||||
CFG_END()
|
||||
};
|
||||
static cfg_opt_t statusbar_opts[] =
|
||||
|
@ -291,6 +298,7 @@ parse_config(Display * disp, int scr,const char *confpatharg, awesome_config *aw
|
|||
awesomeconf->colors_selected[ColBorder] = initxcolor(disp, awesomeconf->phys_screen, cfg_getstr(cfg_colors, "focus_border"));
|
||||
awesomeconf->colors_selected[ColBG] = initxcolor(disp, awesomeconf->phys_screen, cfg_getstr(cfg_colors, "focus_bg"));
|
||||
awesomeconf->colors_selected[ColFG] = initxcolor(disp, awesomeconf->phys_screen, cfg_getstr(cfg_colors, "focus_fg"));
|
||||
awesomeconf->colors_tab[ColBorder] = initxcolor(disp, awesomeconf->phys_screen, cfg_getstr(cfg_colors, "tab_border"));
|
||||
|
||||
/* Statusbar */
|
||||
tmp = cfg_getstr(cfg_statusbar, "position");
|
||||
|
|
13
config.h
13
config.h
|
@ -115,6 +115,17 @@ struct Client
|
|||
Client *next;
|
||||
/** Previous client */
|
||||
Client *prev;
|
||||
/** Tabs support */
|
||||
struct
|
||||
{
|
||||
/** Next client in tab */
|
||||
Client *next;
|
||||
/** Previous client in tab */
|
||||
Client *prev;
|
||||
/** True if client is the visible one */
|
||||
Bool isvisible;
|
||||
/** True if client is tabbed */
|
||||
} tab;
|
||||
/** Window of the client */
|
||||
Window win;
|
||||
/** Client display */
|
||||
|
@ -190,6 +201,8 @@ struct awesome_config
|
|||
XColor colors_normal[ColLast];
|
||||
/** Selected colors */
|
||||
XColor colors_selected[ColLast];
|
||||
/** Tabbed colors */
|
||||
XColor colors_tab[ColLast];
|
||||
/** Cursors */
|
||||
Cursor cursor[CurLast];
|
||||
/** Font */
|
||||
|
|
22
event.c
22
event.c
|
@ -38,8 +38,8 @@
|
|||
#define CLEANMASK(mask, screen) (mask & ~(awesomeconf[screen].numlockmask | LockMask))
|
||||
#define MOUSEMASK (BUTTONMASK | PointerMotionMask)
|
||||
|
||||
static Client *
|
||||
getclient(Client **list, Window w)
|
||||
Client *
|
||||
get_client_bywin(Client **list, Window w)
|
||||
{
|
||||
Client *c;
|
||||
|
||||
|
@ -195,7 +195,7 @@ handle_event_buttonpress(XEvent * e, awesome_config *awesomeconf)
|
|||
return;
|
||||
}
|
||||
|
||||
if((c = getclient(awesomeconf->clients, ev->window)))
|
||||
if((c = get_client_bywin(awesomeconf->clients, ev->window)))
|
||||
{
|
||||
focus(c->display, c, ev->same_screen, &awesomeconf[c->screen]);
|
||||
if(CLEANMASK(ev->state, c->screen) != awesomeconf[c->screen].modkey)
|
||||
|
@ -255,7 +255,7 @@ handle_event_configurerequest(XEvent * e, awesome_config *awesomeconf)
|
|||
XConfigureRequestEvent *ev = &e->xconfigurerequest;
|
||||
XWindowChanges wc;
|
||||
|
||||
if((c = getclient(awesomeconf->clients, ev->window)))
|
||||
if((c = get_client_bywin(awesomeconf->clients, ev->window)))
|
||||
{
|
||||
c->ismax = False;
|
||||
if(ev->value_mask & CWBorderWidth)
|
||||
|
@ -338,7 +338,7 @@ handle_event_destroynotify(XEvent * e, awesome_config *awesomeconf)
|
|||
Client *c;
|
||||
XDestroyWindowEvent *ev = &e->xdestroywindow;
|
||||
|
||||
if((c = getclient(awesomeconf->clients, ev->window)))
|
||||
if((c = get_client_bywin(awesomeconf->clients, ev->window)))
|
||||
unmanage(c, WithdrawnState, &awesomeconf[c->screen]);
|
||||
}
|
||||
|
||||
|
@ -351,7 +351,7 @@ handle_event_enternotify(XEvent * e, awesome_config *awesomeconf)
|
|||
|
||||
if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
|
||||
return;
|
||||
if((c = getclient(awesomeconf->clients, ev->window)))
|
||||
if((c = get_client_bywin(awesomeconf->clients, ev->window)))
|
||||
{
|
||||
if(!*awesomeconf->client_sel || *awesomeconf->client_sel != c)
|
||||
{
|
||||
|
@ -444,7 +444,7 @@ handle_event_maprequest(XEvent * e, awesome_config *awesomeconf)
|
|||
return;
|
||||
if(wa.override_redirect)
|
||||
return;
|
||||
if(!getclient(awesomeconf->clients, ev->window))
|
||||
if(!get_client_bywin(awesomeconf->clients, ev->window))
|
||||
{
|
||||
for(screen = 0; wa.screen != ScreenOfDisplay(e->xany.display, screen); screen++);
|
||||
if(screen == 0)
|
||||
|
@ -469,13 +469,13 @@ handle_event_propertynotify(XEvent * e, awesome_config *awesomeconf)
|
|||
|
||||
if(ev->state == PropertyDelete)
|
||||
return; /* ignore */
|
||||
if((c = getclient(awesomeconf->clients, ev->window)))
|
||||
if((c = get_client_bywin(awesomeconf->clients, ev->window)))
|
||||
{
|
||||
switch (ev->atom)
|
||||
{
|
||||
case XA_WM_TRANSIENT_FOR:
|
||||
XGetTransientForHint(e->xany.display, c->win, &trans);
|
||||
if(!c->isfloating && (c->isfloating = (getclient(awesomeconf->clients, trans) != NULL)))
|
||||
if(!c->isfloating && (c->isfloating = (get_client_bywin(awesomeconf->clients, trans) != NULL)))
|
||||
arrange(e->xany.display, &awesomeconf[c->screen]);
|
||||
break;
|
||||
case XA_WM_NORMAL_HINTS:
|
||||
|
@ -497,7 +497,7 @@ handle_event_unmapnotify(XEvent * e, awesome_config *awesomeconf)
|
|||
Client *c;
|
||||
XUnmapEvent *ev = &e->xunmap;
|
||||
|
||||
if((c = getclient(awesomeconf->clients, ev->window))
|
||||
if((c = get_client_bywin(awesomeconf->clients, ev->window))
|
||||
&& ev->event == RootWindow(e->xany.display, c->phys_screen) && (ev->send_event || !c->unmapped))
|
||||
unmanage(c, WithdrawnState, &awesomeconf[c->screen]);
|
||||
}
|
||||
|
@ -507,7 +507,7 @@ handle_event_shape(XEvent * e,
|
|||
awesome_config *awesomeconf __attribute__ ((unused)))
|
||||
{
|
||||
XShapeEvent *ev = (XShapeEvent *) e;
|
||||
Client *c = getclient(awesomeconf->clients, ev->window);
|
||||
Client *c = get_client_bywin(awesomeconf->clients, ev->window);
|
||||
|
||||
if(c)
|
||||
set_shape(c);
|
||||
|
|
1
event.h
1
event.h
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
Client * get_client_bywin(Client **list, Window w);
|
||||
void grabkeys(Display *, int, awesome_config *); /* grab all keys defined in config */
|
||||
|
||||
void handle_event_buttonpress(XEvent *, awesome_config *);
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* tab.c - tab management
|
||||
*
|
||||
* Copyright © 2007 Julien Danjou <julien@danjou.info>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tab.h"
|
||||
#include "event.h"
|
||||
#include "layout.h"
|
||||
|
||||
void
|
||||
uicb_tab(awesome_config *awesomeconf,
|
||||
const char *arg __attribute__ ((unused)))
|
||||
{
|
||||
Window dummy, child;
|
||||
int x1, y1, di;
|
||||
unsigned int dui;
|
||||
XEvent ev;
|
||||
Client *sel = *awesomeconf->client_sel, *c = NULL, *tmp;
|
||||
|
||||
if(XGrabPointer(awesomeconf->display, RootWindow(awesomeconf->display, awesomeconf->phys_screen),
|
||||
False, ButtonPressMask, GrabModeAsync, GrabModeAsync, None,
|
||||
awesomeconf[awesomeconf->screen].cursor[CurMove], CurrentTime) != GrabSuccess)
|
||||
return;
|
||||
|
||||
|
||||
for(;;)
|
||||
{
|
||||
XMaskEvent(awesomeconf->display, ButtonPressMask, &ev);
|
||||
if(ev.type == ButtonPress)
|
||||
{
|
||||
XUngrabPointer(awesomeconf->display, CurrentTime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
XQueryPointer(awesomeconf->display,
|
||||
RootWindow(awesomeconf->display, awesomeconf->phys_screen),
|
||||
&dummy, &child, &x1, &y1, &di, &di, &dui);
|
||||
if((c = get_client_bywin(awesomeconf->clients, child))
|
||||
&& c != sel)
|
||||
{
|
||||
/* take the last tabbed window */
|
||||
for(tmp = sel; tmp->tab.next; tmp = tmp->tab.next);
|
||||
tmp->tab.next = c;
|
||||
c->tab.prev = tmp;
|
||||
|
||||
c->tab.isvisible = False;
|
||||
arrange(awesomeconf->display, awesomeconf);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
uicb_untab(awesome_config *awesomeconf,
|
||||
const char *arg __attribute__ ((unused)))
|
||||
{
|
||||
Client *tmp, *sel = *awesomeconf->client_sel;
|
||||
|
||||
if(!sel)
|
||||
return;
|
||||
|
||||
if(sel->tab.next)
|
||||
sel->tab.next->tab.isvisible = True;
|
||||
else if(sel->tab.prev)
|
||||
sel->tab.prev->tab.isvisible = True;
|
||||
|
||||
sel->tab.isvisible = True;
|
||||
|
||||
if(sel->tab.next)
|
||||
sel->tab.next->tab.prev = sel->tab.prev;
|
||||
|
||||
tmp = sel->tab.next;
|
||||
sel->tab.next = NULL;
|
||||
|
||||
if(sel->tab.prev)
|
||||
sel->tab.prev->tab.next = tmp;
|
||||
|
||||
sel->tab.prev = NULL;
|
||||
|
||||
arrange(awesomeconf->display, awesomeconf);
|
||||
}
|
||||
|
||||
void
|
||||
uicb_viewnexttab(awesome_config *awesomeconf,
|
||||
const char *arg __attribute__ ((unused)))
|
||||
{
|
||||
Client *sel = *awesomeconf->client_sel;
|
||||
|
||||
if(!sel || !sel->tab.next)
|
||||
return;
|
||||
|
||||
sel->tab.isvisible = False;
|
||||
sel->tab.next->tab.isvisible = True;
|
||||
arrange(awesomeconf->display, awesomeconf);
|
||||
focus(awesomeconf->display, sel->tab.next, True, awesomeconf);
|
||||
}
|
||||
|
||||
void
|
||||
uicb_viewprevtab(awesome_config *awesomeconf,
|
||||
const char *arg __attribute__ ((unused)))
|
||||
{
|
||||
Client *sel = *awesomeconf->client_sel;
|
||||
|
||||
if(!sel || !sel->tab.prev)
|
||||
return;
|
||||
|
||||
sel->tab.isvisible = False;
|
||||
sel->tab.prev->tab.isvisible = True;
|
||||
arrange(awesomeconf->display, awesomeconf);
|
||||
focus(awesomeconf->display, sel->tab.prev, True, awesomeconf);
|
||||
}
|
||||
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* tab.h - tab management header
|
||||
*
|
||||
* Copyright © 2007 Julien Danjou <julien@danjou.info>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AWESOME_TAB_H
|
||||
#define AWESOME_TAB_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
UICB_PROTO(uicb_tab);
|
||||
UICB_PROTO(uicb_untab);
|
||||
UICB_PROTO(uicb_viewnexttab);
|
||||
UICB_PROTO(uicb_viewprevtab);
|
||||
|
||||
#endif
|
||||
// vim: filetype=c:expandtab:shiftwidth=6:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99
|
Loading…
Reference in New Issue