Menu/layout: Add menu.c & Menu for layout switch (or just switch, manage it in the conf layout { system = "menu/switch"})
This commit is contained in:
parent
b49f81d83b
commit
13363877f7
@ -39,6 +39,7 @@ set(wmfs_src
|
||||
src/infobar.c
|
||||
src/init.c
|
||||
src/layout.c
|
||||
src/menu.c
|
||||
src/mouse.c
|
||||
src/screen.c
|
||||
src/tag.c
|
||||
|
||||
16
src/config.c
16
src/config.c
@ -64,7 +64,8 @@ conf_init_func_list(void)
|
||||
{"screen_next", uicb_screen_next },
|
||||
{"screen_prev", uicb_screen_prev },
|
||||
{"reload", uicb_reload },
|
||||
{"launcher", uicb_launcher }
|
||||
{"launcher", uicb_launcher },
|
||||
{"set_layout", uicb_set_layout }
|
||||
};
|
||||
|
||||
func_list = emalloc(LEN(tmp_list), sizeof(func_name_list_t));
|
||||
@ -154,7 +155,7 @@ conf_root_section(cfg_t *cfg_r)
|
||||
void
|
||||
conf_client_section(cfg_t *cfg_c)
|
||||
{
|
||||
/* Client misc */
|
||||
/* Client misc */
|
||||
conf.client.borderheight = (cfg_getint(cfg_c, "border_height")) ? cfg_getint(cfg_c, "border_height") : 1;
|
||||
conf.client.place_at_mouse = cfg_getbool(cfg_c, "place_at_mouse");
|
||||
conf.client.bordernormal = getcolor(alias_to_str(cfg_getstr(cfg_c, "border_normal")));
|
||||
@ -195,6 +196,9 @@ conf_layout_section(cfg_t *cfg_l)
|
||||
conf.colors.layout_fg = strdup(alias_to_str(cfg_getstr(cfg_l, "fg")));
|
||||
conf.colors.layout_bg = getcolor(alias_to_str(cfg_getstr(cfg_l, "bg")));
|
||||
|
||||
if(strcmp(strdup(alias_to_str(cfg_getstr(cfg_l, "system"))), "menu") == 0)
|
||||
conf.layout_system = True;
|
||||
|
||||
if((conf.nlayout = cfg_size(cfg_l, "layout")) > NUM_OF_LAYOUT
|
||||
|| !(conf.nlayout = cfg_size(cfg_l, "layout")))
|
||||
{
|
||||
@ -204,6 +208,9 @@ conf_layout_section(cfg_t *cfg_l)
|
||||
conf.layout[0].func = tile;
|
||||
}
|
||||
|
||||
if(conf.layout_system)
|
||||
menu_init(&menulayout, conf.nlayout);
|
||||
|
||||
if(!conf.layout[0].symbol
|
||||
&& !conf.layout[0].func)
|
||||
{
|
||||
@ -218,6 +225,11 @@ conf_layout_section(cfg_t *cfg_l)
|
||||
}
|
||||
else
|
||||
{
|
||||
if(conf.layout_system)
|
||||
menu_new_item(&menulayout.item[i],
|
||||
strdup(alias_to_str(cfg_getstr(cfgtmp, "symbol"))),
|
||||
uicb_set_layout, strdup(cfg_getstr(cfgtmp, "type")));
|
||||
|
||||
conf.layout[i].symbol = strdup(alias_to_str(cfg_getstr(cfgtmp, "symbol")));
|
||||
conf.layout[i].func = name_to_func(strdup(cfg_getstr(cfgtmp, "type")), layout_list);
|
||||
}
|
||||
|
||||
@ -107,6 +107,7 @@ cfg_opt_t layouts_opts[] =
|
||||
CFG_STR("fg", "#FFFFFF", CFGF_NONE),
|
||||
CFG_STR("bg", "#292929", CFGF_NONE),
|
||||
CFG_BOOL("border", cfg_false, CFGF_NONE),
|
||||
CFG_STR("system", "menu", CFGF_NONE),
|
||||
CFG_SEC("layout", layout_opts, CFGF_MULTI),
|
||||
CFG_END()
|
||||
};
|
||||
|
||||
@ -99,3 +99,5 @@ textw(const char *text)
|
||||
|
||||
return gl.width + font->descent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
20
src/event.c
20
src/event.c
@ -85,11 +85,25 @@ buttonpress(XButtonEvent *ev)
|
||||
|
||||
/* Layout button */
|
||||
if(ev->window == infobar[selscreen].layout_button->win)
|
||||
switch(ev->button)
|
||||
{
|
||||
if(conf.layout_system &&
|
||||
(ev->button == Button1 || ev->button == Button3)) /* True -> menu */
|
||||
{
|
||||
case Button1: case Button4: layoutswitch(True); break;
|
||||
case Button3: case Button5: layoutswitch(False); break;
|
||||
int y = infobar[selscreen].layout_button->geo.y + INFOBARH;
|
||||
if(infobar[selscreen].geo.y != sgeo[selscreen].y - (INFOBARH + TBARH))
|
||||
y = infobar[selscreen].geo.y - (INFOBARH * menulayout.nitem) - SHADH;
|
||||
|
||||
menu_draw(menulayout, infobar[selscreen].layout_button->geo.x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(ev->button)
|
||||
{
|
||||
case Button1: case Button4: layoutswitch(True); break;
|
||||
case Button3: case Button5: layoutswitch(False); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -214,22 +214,25 @@ uicb_launcher(uicb_t cmd)
|
||||
char buf[512] = { 0 };
|
||||
int pos = 0;
|
||||
int lrun = 1;
|
||||
BarWindow *launch = barwin_create(infobar[screen_get_sel()].bar->win,
|
||||
|
||||
screen_get_sel();
|
||||
|
||||
BarWindow *launch = barwin_create(infobar[selscreen].bar->win,
|
||||
/* X */
|
||||
(infobar[selscreen].layout_button->geo.x
|
||||
+ textw(tags[selscreen][seltag[selscreen]].layout.symbol) + PAD),
|
||||
/* Y */
|
||||
0,
|
||||
SHADH,
|
||||
/* WIDTH */
|
||||
(sgeo[selscreen].width
|
||||
(sgeo[0].width
|
||||
- (infobar[selscreen].layout_button->geo.x
|
||||
+ textw(tags[selscreen][seltag[selscreen]].layout.symbol) + PAD)),
|
||||
+ textw(tags[selscreen][seltag[selscreen]].layout.symbol) + PAD) - SHADH),
|
||||
/* HEIGHT */
|
||||
infobar[selscreen].geo.height,
|
||||
infobar[selscreen].geo.height - SHADH,
|
||||
/* COLOR */
|
||||
conf.colors.bar, conf.colors.text,
|
||||
/* OPTION */
|
||||
False, False, False);
|
||||
False, False, True);
|
||||
barwin_map(launch);
|
||||
barwin_refresh_color(launch);
|
||||
/* Draw Prompt */
|
||||
|
||||
34
src/layout.c
34
src/layout.c
@ -505,3 +505,37 @@ uicb_togglemax(uicb_t cmd)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** Set the layout
|
||||
* \param cmd uicb_t type
|
||||
*/
|
||||
void
|
||||
uicb_set_layout(uicb_t cmd)
|
||||
{
|
||||
int i = -1;
|
||||
|
||||
screen_get_sel();
|
||||
|
||||
if(strcmp(cmd, "tile_right") == 0
|
||||
|| strcmp(cmd, "tile") == 0)
|
||||
i = 0;
|
||||
else if(strcmp(cmd, "tile_left") == 0)
|
||||
i = 1;
|
||||
else if(strcmp(cmd, "tile_top") == 0)
|
||||
i = 2;
|
||||
else if(strcmp(cmd, "tile_bottom") == 0)
|
||||
i = 3;
|
||||
else if(strcmp(cmd, "tile_grid") == 0)
|
||||
i = 4;
|
||||
else if(strcmp(cmd, "max") == 0)
|
||||
i = 5;
|
||||
else if(strcmp(cmd, "free") == 0)
|
||||
i = 6;
|
||||
|
||||
if(i >= 0)
|
||||
tags[selscreen][seltag[selscreen]].layout = conf.layout[i];
|
||||
|
||||
arrange(selscreen);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
150
src/menu.c
Normal file
150
src/menu.c
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* menu.c
|
||||
* Copyright © 2008 Martin Duquesnoy <xorg62@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of the nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "wmfs.h"
|
||||
|
||||
void
|
||||
menu_init(Menu *menu, int nitem)
|
||||
{
|
||||
menu->nitem = nitem;
|
||||
menu->item = emalloc(sizeof(MenuItem), nitem);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
menu_new_item(MenuItem *mi, char *name, void *func, char *cmd)
|
||||
{
|
||||
mi->name = name;
|
||||
mi->func = func;
|
||||
mi->cmd = cmd;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
menu_draw(Menu menu, int x, int y)
|
||||
{
|
||||
int i, width;
|
||||
int r = 1;
|
||||
XEvent ev;
|
||||
BarWindow *item[menu.nitem];
|
||||
BarWindow *frame;
|
||||
|
||||
width = menu_get_longer_string(menu.item, menu.nitem);
|
||||
|
||||
/* Frame barwin */
|
||||
frame = barwin_create(ROOT, x, y, width + SHADH,
|
||||
menu.nitem * INFOBARH + SHADH,
|
||||
conf.colors.bar, conf.colors.text,
|
||||
False, False, True);
|
||||
|
||||
barwin_map(frame);
|
||||
barwin_map_subwin(frame);
|
||||
barwin_refresh_color(frame);
|
||||
|
||||
for(i = 0; i < menu.nitem; ++i)
|
||||
{
|
||||
item[i] = barwin_create(frame->win,
|
||||
SHADH,
|
||||
(i * INFOBARH) + SHADH,
|
||||
width - SHADH,
|
||||
INFOBARH,
|
||||
conf.colors.bar,
|
||||
conf.colors.text,
|
||||
True, False, False);
|
||||
barwin_map(item[i]);
|
||||
barwin_map_subwin(frame);
|
||||
barwin_refresh_color(item[i]);
|
||||
barwin_refresh(item[i]);
|
||||
|
||||
barwin_draw_text(item[i], ((width / 2) - (textw(menu.item[i].name) / 2)), font->height, menu.item[i].name);
|
||||
}
|
||||
|
||||
while(r)
|
||||
{
|
||||
switch(ev.type)
|
||||
{
|
||||
case ButtonPress:
|
||||
/* Execute the function linked with the item */
|
||||
for(i = 0; i < menu.nitem; ++i)
|
||||
if(ev.xbutton.window == item[i]->win
|
||||
&& ev.xbutton.button == Button1)
|
||||
if(menu.item[i].func)
|
||||
menu.item[i].func(menu.item[i].cmd);
|
||||
r = 0;
|
||||
break;
|
||||
case EnterNotify:
|
||||
/* For focus an item with the mousw */
|
||||
for(i = 0; i < menu.nitem; ++i)
|
||||
{
|
||||
if(ev.xcrossing.window == item[i]->win)
|
||||
{
|
||||
item[i]->fg = conf.colors.tagselfg;
|
||||
item[i]->bg = conf.colors.tagselbg;
|
||||
}
|
||||
else
|
||||
{
|
||||
item[i]->fg = conf.colors.text;
|
||||
item[i]->bg = conf.colors.bar;
|
||||
}
|
||||
|
||||
barwin_refresh_color(item[i]);
|
||||
barwin_draw_text(item[i], ((width / 2) - (textw(menu.item[i].name) / 2)), font->height, menu.item[i].name);
|
||||
barwin_refresh(item[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
getevent(ev);
|
||||
break;
|
||||
}
|
||||
XNextEvent(dpy, &ev);
|
||||
}
|
||||
|
||||
for(i = 0; i < menu.nitem; ++i)
|
||||
barwin_delete(item[i]);
|
||||
barwin_delete(frame);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
menu_get_longer_string(MenuItem *mt, int nitem)
|
||||
{
|
||||
int i, l = 0;
|
||||
|
||||
for(i = 0; i < nitem; ++i)
|
||||
if(textw(mt[i].name) > l)
|
||||
l = textw(mt[i].name);
|
||||
|
||||
return l + PAD;
|
||||
}
|
||||
@ -200,6 +200,24 @@ typedef struct
|
||||
Layout layout;
|
||||
} Tag;
|
||||
|
||||
/* Menu Item Struct */
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
void (*func)(uicb_t);
|
||||
uicb_t cmd;
|
||||
} MenuItem;
|
||||
|
||||
/* Menu Struct */
|
||||
typedef struct
|
||||
{
|
||||
int specified_pos, x, y;
|
||||
/* Number of item */
|
||||
int nitem;
|
||||
/* Item */
|
||||
MenuItem *item;
|
||||
} Menu;
|
||||
|
||||
/* Alias struct */
|
||||
typedef struct
|
||||
{
|
||||
@ -267,6 +285,7 @@ typedef struct
|
||||
Layout layout[NUM_OF_LAYOUT];
|
||||
int *ntag;
|
||||
Bool tag_round;
|
||||
Bool layout_system; /* Switch: False, Menu: True. */
|
||||
int nkeybind;
|
||||
int nbutton;
|
||||
int nlayout;
|
||||
|
||||
14
src/util.c
14
src/util.c
@ -180,6 +180,20 @@ alias_to_str(char *conf_choice)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/** Get the mouse pointer position.
|
||||
*/
|
||||
XRectangle
|
||||
get_mouse_pos(void)
|
||||
{
|
||||
Window dum;
|
||||
int d, u;
|
||||
XRectangle ret;
|
||||
|
||||
XQueryPointer(dpy, ROOT, &dum, &dum, (int*)&ret.x, (int*)&ret.y, &d, &d, (uint *)&u);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Execute a sh command
|
||||
* \param cmd Command
|
||||
*/
|
||||
|
||||
13
src/wmfs.h
13
src/wmfs.h
@ -95,7 +95,6 @@ BarWindow *barwin_create(Window parent,
|
||||
Bool entermask,
|
||||
Bool stipple,
|
||||
Bool border);
|
||||
|
||||
void barwin_draw_text(BarWindow *bw, int x, int y, char *text);
|
||||
void barwin_delete(BarWindow *bw);
|
||||
void barwin_delete_subwin(BarWindow *bw);
|
||||
@ -194,6 +193,12 @@ void maprequest(XMapRequestEvent *ev);
|
||||
void propertynotify(XPropertyEvent *ev);
|
||||
void getevent(XEvent ev);
|
||||
|
||||
/* menu.c */
|
||||
void menu_init(Menu *menu, int nitem);
|
||||
void menu_new_item(MenuItem *mi, char *name, void *func, char *cmd);
|
||||
void menu_draw(Menu menu, int x, int y);
|
||||
int menu_get_longer_string(MenuItem *mt, int nitem);
|
||||
|
||||
/* mouse.c */
|
||||
void mouse_move(Client *c);
|
||||
void mouse_resize(Client *c);
|
||||
@ -213,6 +218,7 @@ uint char_to_button(char *name, name_to_uint_t blist[]);
|
||||
Layout layout_name_to_struct(Layout lt[], char *name, int n, func_name_list_t llist[]);
|
||||
char* alias_to_str(char *conf_choice);
|
||||
/* }}} */
|
||||
XRectangle get_mouse_pos(void);
|
||||
void uicb_spawn(uicb_t);
|
||||
|
||||
/* tag.c */
|
||||
@ -223,7 +229,7 @@ void uicb_tag_next(uicb_t);
|
||||
void uicb_tag_prev(uicb_t);
|
||||
void uicb_tagtransfert(uicb_t);
|
||||
|
||||
/* screen */
|
||||
/* screen.c */
|
||||
int screen_count(void);
|
||||
XRectangle screen_get_geo(int s);
|
||||
int screen_get_with_geo(int x, int y);
|
||||
@ -254,6 +260,8 @@ void uicb_layout_prev(uicb_t);
|
||||
void uicb_layout_next(uicb_t);
|
||||
void uicb_set_mwfact(uicb_t);
|
||||
void uicb_set_nmaster(uicb_t);
|
||||
void uicb_set_layout(uicb_t cmd);
|
||||
|
||||
|
||||
/* init.c */
|
||||
void init(void);
|
||||
@ -295,6 +303,7 @@ Atom net_atom[net_last];
|
||||
InfoBar *infobar;
|
||||
Tag **tags;
|
||||
int *seltag;
|
||||
Menu menulayout;
|
||||
|
||||
/* Important Client */
|
||||
Client *clients;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user