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:
Martin Duquesnoy 2009-01-31 18:39:49 +01:00
parent b49f81d83b
commit 13363877f7
12 changed files with 275 additions and 13 deletions

View File

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

View File

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

View File

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

View File

@ -99,3 +99,5 @@ textw(const char *text)
return gl.width + font->descent;
}

View File

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

View File

@ -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 */

View File

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

View File

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

View File

@ -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
*/

View File

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

3
wmfsrc
View File

@ -27,6 +27,9 @@ layouts
# Border around the layout button
border = true
system = "menu" # menu or switch
# Tiling layouts
layout { type = "tile_right" symbol = "RIGHT" }
layout { type = "tile_left" symbol = "LEFT" }