diff --git a/python/.gitignore b/python/.gitignore new file mode 100644 index 0000000..5975d97 --- /dev/null +++ b/python/.gitignore @@ -0,0 +1,2 @@ +*~ +build/ diff --git a/python/libwmfs.c b/python/libwmfs.c new file mode 100644 index 0000000..e978a34 --- /dev/null +++ b/python/libwmfs.c @@ -0,0 +1,185 @@ +/* + * libwmfs.c + * Copyright © 2008 Martin Duquesnoy + * 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 "libwmfs.h" + +/* Set Methods */ +static PyMethodDef WmfsMethods[] = +{ + {"init", wmfs_init, METH_VARARGS, "Init wmfs module"}, + {"statustext", wmfs_statustext, METH_VARARGS, "Wrote in the statustext"}, + {"tag_set", wmfs_tag_set, METH_VARARGS, "Set a tag"}, + {"screen_set", wmfs_screen_set, METH_VARARGS, "Set the selected screen"}, + {"screen_get_current", wmfs_screen_get_cur, METH_VARARGS, "Get the current screen number"}, + {"screen_count", wmfs_screen_count, METH_VARARGS, "Get how many screen there are"}, + {"spawn", wmfs_spawn, METH_VARARGS, "Execute a command"}, + /* Sentinel */ + {NULL, NULL, 0, NULL} +}; + +void +send_client_message(char* atom_name, long data_l[5]) +{ + XEvent ev; + int i; + + ev.xclient.type = ClientMessage; + ev.xclient.serial = 0; + ev.xclient.send_event = True; + ev.xclient.message_type = ATOM(atom_name); + ev.xclient.window = ROOT; + ev.xclient.format = 32; + + for(i = 0; i < 6; ++i) + ev.xclient.data.l[i] = data_l[i]; + + XSendEvent(dpy, ROOT, False, SubstructureRedirectMask|SubstructureNotifyMask, &ev); + XSync(dpy, False); + + return; +} + +PyObject* +wmfs_init(PyObject *self, PyObject *args) +{ + Atom rt; + int rf; + unsigned long ir, il; + unsigned char *ret; + + PyArg_ParseTuple(args, ""); + + if(!(dpy = XOpenDisplay(NULL))) + { + fprintf(stderr, "wmfs-control: cannot open X server.\n"); + exit(EXIT_FAILURE); + } + + /* Check if wmfs is running */ + XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_RUNNING"), 0L, 4096, + False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret); + + /* Else, exit. */ + if(!ret) + { + fprintf(stderr, "WMFS is not running.\n"); + XFree(ret); + exit(EXIT_FAILURE); + } + XFree(ret); + + inited = True; + + Py_INCREF(Py_None); + + return Py_None; +} + + +PyObject* +wmfs_statustext(PyObject *self, PyObject *args) +{ + char *arg; + long data[5]; + + if(!PyArg_ParseTuple(args, "s", &arg)) + return NULL; + + data[4] = True; + + XChangeProperty(dpy, ROOT, ATOM("_WMFS_STATUSTEXT"), ATOM("UTF8_STRING"), + 8, PropModeReplace, (unsigned char*)arg, strlen(arg)); + + send_client_message("_WMFS_STATUSTEXT", data); + + Py_INCREF(Py_None); + + return Py_None; +} + +PyObject* +wmfs_spawn(PyObject *self, PyObject *args) +{ + char *arg, *sh; + + Py_INCREF(Py_None); + + if(!PyArg_ParseTuple(args, "s", &arg)) + return NULL; + + if(!(sh = getenv("SHELL"))) + sh = "/bin/sh"; + if(!strlen(arg)) + return Py_None; /* Error ? */ + + if(fork() == 0) + { + if(fork() == 0) + { + setsid(); + execl(sh, sh, "-c", arg, (char*)NULL); + } + exit(EXIT_SUCCESS); + } + + + return Py_None; +} + + +PyMODINIT_FUNC +initwmfs(void) +{ + PyObject *m = Py_InitModule("wmfs", WmfsMethods); + + if(m == NULL) + return; + + WmfsInitError = PyErr_NewException("wmfs.error", NULL, NULL); + + Py_INCREF(WmfsInitError); + PyModule_AddObject(m, "error", WmfsInitError); +} + +int +main(int argc, char **argv) +{ + Py_SetProgramName(argv[0]); + + /* Initialize the Python interpreter. Required. */ + Py_Initialize(); + + /* Init Module */ + initwmfs(); + + return 0; +} diff --git a/python/libwmfs.h b/python/libwmfs.h new file mode 100644 index 0000000..8b4e644 --- /dev/null +++ b/python/libwmfs.h @@ -0,0 +1,61 @@ +/* + * libwmfs.h + * Copyright © 2008 Martin Duquesnoy + * 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 + +#include +#include +#include + +/* Xlib util macro */ +#define ROOT RootWindow(dpy, SCREEN) +#define ATOM(a) XInternAtom(dpy, a, False) +#define SCREEN DefaultScreen(dpy) + +/* Prototypes */ + +/* screen_func.c */ +PyObject* wmfs_screen_set(PyObject *self, PyObject *args); +PyObject* wmfs_screen_get_cur(PyObject *self, PyObject *args); +PyObject* wmfs_screen_count(PyObject *self, PyObject *args); + +/* tag_func.c */ +PyObject* wmfs_tag_set(PyObject *self, PyObject *args); + +/* libwmfs.c */ +PyObject* wmfs_init(PyObject *self, PyObject *args); +PyObject* wmfs_statustext(PyObject *self, PyObject *args); +PyObject* wmfs_spawn(PyObject *self, PyObject *args); + +Display *dpy; +static PyObject *WmfsInitError; +Bool inited; diff --git a/python/screen_func.c b/python/screen_func.c new file mode 100644 index 0000000..8ead8b2 --- /dev/null +++ b/python/screen_func.c @@ -0,0 +1,96 @@ +/* + * screen_func.c + * Copyright © 2008 Martin Duquesnoy + * 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 "libwmfs.h" + +PyObject* +wmfs_screen_set(PyObject *self, PyObject *args) +{ + long data[5]; + int arg; + + if(!PyArg_ParseTuple(args, "i", &arg)) + return NULL; + + data[0] = arg; + + send_client_message("_WMFS_SET_SCREEN", data); + + Py_INCREF(Py_None); + + return Py_None; +} + + +PyObject* +wmfs_screen_get_cur(PyObject *self, PyObject *args) +{ + Atom rt; + int rf; + unsigned long ir, il; + unsigned char *ret; + int i = 0; + + PyArg_ParseTuple(args, ""); + + if(XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_CURRENT_SCREEN"), 0L, 4096, + False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success); + { + i = *(long*)ret; + XFree(ret); + } + + return Py_BuildValue("i", i); +} + +PyObject* +wmfs_screen_count(PyObject *self, PyObject *args) +{ + Atom rt; + int rf; + unsigned long ir, il; + unsigned char *ret; + int i = 1; + + PyArg_ParseTuple(args, ""); + + if(XGetWindowProperty(dpy, ROOT, ATOM("_WMFS_SCREEN_COUNT"), 0L, 4096, + False, XA_CARDINAL, &rt, &rf, &ir, &il, &ret) == Success); + { + i = *(long*)ret; + XFree(ret); + } + + printf("screen count: %i\n", i); + + return Py_BuildValue("i", i); +} diff --git a/python/setup.py b/python/setup.py new file mode 100644 index 0000000..63f1b07 --- /dev/null +++ b/python/setup.py @@ -0,0 +1,21 @@ +from distutils.core import setup, Extension + +module1 = Extension('wmfs', + #include_dirs = ['/usr/local/include'], + libraries = ['X11'], + #library_dirs = ['/usr/local/lib'], + sources = ['screen_func.c', + 'tag_func.c', + 'libwmfs.c']) + +setup (name = 'wmfs', + version = '0.1', + description = 'desc', + author = 'author', + author_email = 'mail', + url = 'http://wmfs.sangor.net/', + long_description = ''' +desc long +''', + ext_modules = [module1]) + diff --git a/python/tag_func.c b/python/tag_func.c new file mode 100644 index 0000000..d24e458 --- /dev/null +++ b/python/tag_func.c @@ -0,0 +1,52 @@ +/* + * tag_func.c + * Copyright © 2008 Martin Duquesnoy + * 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 "libwmfs.h" + +PyObject* +wmfs_tag_set(PyObject *self, PyObject *args) +{ + long data[5]; + int arg; + + if(!PyArg_ParseTuple(args, "i", &arg)) + return NULL; + + if(arg >= 0) + data[0] = arg; + + send_client_message("_NET_CURRENT_DESKTOP", data); + + Py_INCREF(Py_None); + + return Py_None; +} diff --git a/src/config.c b/src/config.c index aaf6d4d..853c311 100644 --- a/src/config.c +++ b/src/config.c @@ -33,6 +33,48 @@ #include "config_struct.h" +void +conf_init_func_list(void) +{ + int i; + + func_name_list_t tmp_list[] = + { + {"spawn", uicb_spawn }, + {"client_kill", uicb_client_kill }, + {"client_prev", uicb_client_prev }, + {"client_next", uicb_client_next }, + {"toggle_max", uicb_togglemax }, + {"layout_next", uicb_layout_next }, + {"layout_prev", uicb_layout_prev }, + {"tag", uicb_tag }, + {"tag_next", uicb_tag_next }, + {"tag_prev", uicb_tag_prev }, + {"tag_transfert", uicb_tagtransfert }, + {"set_mwfact", uicb_set_mwfact }, + {"set_nmaster", uicb_set_nmaster }, + {"quit", uicb_quit }, + {"toggle_infobar_position", uicb_infobar_togglepos }, + {"mouse_move", uicb_mouse_move }, + {"mouse_resize", uicb_mouse_resize }, + {"client_raise", uicb_client_raise }, + {"tile_switch", uicb_tile_switch }, + {"toggle_free", uicb_togglefree }, + {"screen_select", uicb_screen_select }, + {"screen_next", uicb_screen_next }, + {"screen_prev", uicb_screen_prev }, + {"reload", uicb_reload } + }; + + func_list = emalloc(LEN(tmp_list), sizeof(func_name_list_t)); + + for(i = 0; i < LEN(tmp_list); ++i) + func_list[i] = tmp_list[i]; + + return; +} + + /* The following function are the different configuration section. {{{ */ @@ -301,6 +343,8 @@ init_conf(void) ret = cfg_parse(cfg, final_path); } + conf_init_func_list(); + conf_alias_section(cfg_getsec(cfg, "alias")); conf_misc_section(cfg_getsec(cfg, "misc")); conf_bar_section(cfg_getsec(cfg, "bar")); diff --git a/src/config_struct.h b/src/config_struct.h index 8b51acf..1ccf7c9 100644 --- a/src/config_struct.h +++ b/src/config_struct.h @@ -172,34 +172,6 @@ cfg_opt_t opts[] = CFG_END() }; -func_name_list_t func_list[] = -{ - {"spawn", uicb_spawn }, - {"client_kill", uicb_client_kill }, - {"client_prev", uicb_client_prev }, - {"client_next", uicb_client_next }, - {"toggle_max", uicb_togglemax }, - {"layout_next", uicb_layout_next }, - {"layout_prev", uicb_layout_prev }, - {"tag", uicb_tag }, - {"tag_next", uicb_tag_next }, - {"tag_prev", uicb_tag_prev }, - {"tag_transfert", uicb_tagtransfert }, - {"set_mwfact", uicb_set_mwfact }, - {"set_nmaster", uicb_set_nmaster }, - {"quit", uicb_quit }, - {"toggle_infobar_position", uicb_infobar_togglepos }, - {"mouse_move", uicb_mouse_move }, - {"mouse_resize", uicb_mouse_resize }, - {"client_raise", uicb_client_raise }, - {"tile_switch", uicb_tile_switch }, - {"toggle_free", uicb_togglefree }, - {"screen_select", uicb_screen_select }, - {"screen_next", uicb_screen_next }, - {"screen_prev", uicb_screen_prev }, - {"reload", uicb_reload } -}; - func_name_list_t layout_list[] = { {"tile_right", tile }, diff --git a/src/event.c b/src/event.c index f6c8398..02ed2ae 100644 --- a/src/event.c +++ b/src/event.c @@ -32,6 +32,8 @@ #include "wmfs.h" +//#include "config_struct.h" + /** ButtonPress handle event * \param ev XButtonEvent pointer */ @@ -100,6 +102,9 @@ clientmessageevent(XClientMessageEvent *ev) { Client *c; int i, mess_t = 0; + Atom rt; + int rf; + ulong ir, il; if(ev->format != 32) return; @@ -116,25 +121,87 @@ clientmessageevent(XClientMessageEvent *ev) && ev->data.l[0] < conf.ntag[selscreen]) tag_set((int)(ev->data.l[0] + 1)); + /* Manage _WMFS_SET_SCREEN */ + if(mess_t == wmfs_set_screen + && ev->data.l[0] >= 0 + && ev->data.l[0] <= screen_count()) + screen_set_sel((int)(ev->data.l[0])); + /* Manage _NET_ACTIVE_WINDOW */ else if(mess_t == net_active_window) if((c = client_gb_win(ev->window))) client_focus(c); } + /* Manage _NET_WM_STATE */ if(mess_t == net_wm_state) if((c = client_gb_win(ev->window))) ewmh_manage_net_wm_state(ev->data.l, c); + /* Manage _NET_CLOSE_WINDOW */ if(mess_t == net_close_window) if((c = client_gb_win(ev->window))) client_kill(c); + /* Manage _NET_WM_DESKTOP */ if(mess_t == net_wm_desktop) if((c = client_gb_win(ev->window))) tag_transfert(c, ev->data.l[0]); + /* Manage _WMFS_STATUSTEXT */ + if(mess_t == wmfs_statustext && ev->data.l[4] == True) + { + uchar *ret; + + if(XGetWindowProperty(dpy, ROOT, net_atom[wmfs_statustext], 0, 4096, + False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret) == Success) + { + for(i = 0; i < LEN(statustext); ++i) + statustext[i] = 0; + + strcpy(statustext, (char*)ret); + + for(i = 0; i < screen_count(); ++i) + infobar_draw(i); + + XFree(ret); + } + } + + + if(mess_t == wmfs_function && ev->data.l[4] == True) + { + uchar *ret_func = NULL; + uchar *ret_cmd = NULL; + char *cmd; + + if(XGetWindowProperty(dpy, ROOT, net_atom[wmfs_function], 0, 4096, + False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret_func) == Success) + printf("--> %s -> ", ret_func); + + if(XGetWindowProperty(dpy, ROOT, net_atom[wmfs_cmd], 0, 4096, + False, net_atom[utf8_string], &rt, &rf, &ir, &il, &ret_cmd) == Success) + printf("%s\n", ret_cmd); + + if(strcmp((char*)ret_cmd, "NULL") == 0) + cmd = NULL; + else + strcpy(cmd, (char*)ret_cmd); + + void (*func)(uicb_t) = name_to_func((char*)ret_func, func_list); + + func(cmd); + + if(ret_cmd) + XFree(ret_cmd); + + if(ret_func) + XFree(ret_func); + } + + + return; } diff --git a/src/ewmh.c b/src/ewmh.c index 3e006b0..de454e8 100644 --- a/src/ewmh.c +++ b/src/ewmh.c @@ -42,6 +42,8 @@ void ewmh_init_hints(void) { + int i = 1; + /* EWMH hints */ net_atom[net_supported] = ATOM("_NET_SUPPORTED"); net_atom[net_client_list] = ATOM("_NET_CLIENT_LIST"); @@ -67,13 +69,26 @@ ewmh_init_hints(void) net_atom[net_wm_state_fullscreen] = ATOM("_NET_WM_STATE_FULLSCREEN"); net_atom[net_wm_state_demands_attention] = ATOM("_NET_WM_STATE_DEMANDS_ATTENTION"); net_atom[utf8_string] = ATOM("UTF8_STRING"); + /* WMFS hints */ - net_atom[wmfs_tag_names] = ATOM("_WMFS_TAG_NAMES"); + net_atom[wmfs_running] = ATOM("_WMFS_RUNNING"); + net_atom[wmfs_statustext] = ATOM("_WMFS_STATUSTEXT"); + net_atom[wmfs_set_screen] = ATOM("_WMFS_SET_SCREEN"); + net_atom[wmfs_screen_count] = ATOM("_WMFS_SCREEN_COUNT"); + net_atom[wmfs_current_tag] = ATOM("_WMFS_CURRENT_TAG"); + net_atom[wmfs_current_screen] = ATOM("_WMFS_CURRENT_SCREEN"); net_atom[wmfs_current_layout] = ATOM("_WMFS_CURRENT_LAYOUT"); + net_atom[wmfs_tag_names] = ATOM("_WMFS_TAG_NAMES"); + + net_atom[wmfs_function] = ATOM("_WMFS_FUNCTION"); + net_atom[wmfs_cmd] = ATOM("_WMFS_CMD"); XChangeProperty(dpy, ROOT, net_atom[net_supported], XA_ATOM, 32, PropModeReplace, (uchar*)net_atom, net_last); + XChangeProperty(dpy, ROOT, net_atom[wmfs_running], XA_CARDINAL, 32, + PropModeReplace, (uchar*)&i, 1); + return; } @@ -107,6 +122,11 @@ ewmh_get_current_desktop(void) XChangeProperty(dpy, ROOT, net_atom[net_current_desktop], XA_CARDINAL, 32, PropModeReplace, (uchar*)&t, 1); + /* Current tag name */ + XChangeProperty(dpy, ROOT, net_atom[wmfs_current_tag], net_atom[utf8_string], 8, + PropModeReplace, (uchar*)tags[selscreen][seltag[selscreen]].name, + strlen(tags[selscreen][seltag[selscreen]].name)); + return; } @@ -308,27 +328,3 @@ ewmh_manage_window_type(Client *c) return; } - -/** Get a Window WM State - * \param win Window - * \return The state -*/ -long -ewmh_get_wm_state(Window win) -{ - Atom rt; - int rf; - long ret = WithdrawnState; - ulong ir, il; - uchar *data; - - if(XGetWindowProperty(dpy, win, net_atom[net_wm_state], 0L, 2L, - False, net_atom[net_wm_state], &rt, - &rf, &ir, &il, &data) == Success && ir) - { - ret = *(long *)data; - XFree(data); - } - - return ret; -} diff --git a/src/frame.c b/src/frame.c index 22441c1..0008678 100644 --- a/src/frame.c +++ b/src/frame.c @@ -72,7 +72,7 @@ frame_create(Client *c) if(TBARH) c->titlebar = barwin_create(c->frame, 0, 0, c->frame_geo.width, - TBARH + BORDH, + TBARH + (c->geo.x - c->frame_geo.x), c->colors.frame, c->colors.fg, True, conf.titlebar.stipple); @@ -191,8 +191,7 @@ frame_update(Client *c) XClearWindow(dpy, c->bottom); if(TBARH && (TBARH + BORDH + 1) > font->height) - barwin_draw_text(c->titlebar, - (c->frame_geo.width / 2) - (textw(c->title) / 2), + barwin_draw_text(c->titlebar, (c->frame_geo.width / 2) - (textw(c->title) / 2), (font->height - (font->descent)) + (((TBARH + BORDH) - font->height) / 2), c->title); diff --git a/src/infobar.c b/src/infobar.c index 964c0f4..a1f4a10 100644 --- a/src/infobar.c +++ b/src/infobar.c @@ -135,13 +135,10 @@ infobar_draw_taglist(int sc) { if(c->screen == sc) { - infobar[sc].tags[c->tag]->bg = ((c->tag == seltag[sc]) - ? conf.colors.tagselbg - : conf.colors.tag_occupied_bg); + infobar[sc].tags[c->tag]->bg = ((c->tag == seltag[sc]) ? conf.colors.tagselbg : conf.colors.tag_occupied_bg); barwin_refresh_color(infobar[sc].tags[i]); } } - if(tags[sc][i].name) barwin_draw_text(infobar[sc].tags[i], PAD / 2, font->height, tags[sc][i].name); } diff --git a/src/init.c b/src/init.c index 14c82f2..8ebb957 100644 --- a/src/init.c +++ b/src/init.c @@ -44,7 +44,6 @@ init(void) init_key(); init_root(); screen_init_geo(); - ewmh_init_hints(); infobar_init(); ewmh_get_current_desktop(); grabkeys(); diff --git a/src/screen.c b/src/screen.c index c809945..3bbce25 100644 --- a/src/screen.c +++ b/src/screen.c @@ -45,6 +45,10 @@ screen_count(void) else n = ScreenCount(dpy); + /* Set _WMFS_SCREEN_COUNT */ + XChangeProperty(dpy, ROOT, net_atom[wmfs_screen_count], XA_CARDINAL, 32, + PropModeReplace, (uchar*)&n, 1); + return n; } @@ -135,6 +139,10 @@ screen_get_sel(void) XQueryPointer(dpy, ROOT, &w, &w, &x, &y, &d, &d, (uint *)&u); selscreen = screen_get_with_geo(x, y); + + /* Set _WMFS_CURRENT_SCREEN */ + XChangeProperty(dpy, ROOT, net_atom[wmfs_current_screen], XA_CARDINAL, 32, + PropModeReplace, (uchar*)&selscreen, 1); } return selscreen; diff --git a/src/structs.h b/src/structs.h index 3f1b314..8d20706 100644 --- a/src/structs.h +++ b/src/structs.h @@ -78,8 +78,16 @@ enum net_wm_state_demands_attention, utf8_string, /* WMFS HINTS */ + wmfs_running, wmfs_tag_names, + wmfs_current_tag, + wmfs_current_screen, wmfs_current_layout, + wmfs_set_screen, + wmfs_screen_count, + wmfs_statustext, + wmfs_function, + wmfs_cmd, net_last }; diff --git a/src/util.c b/src/util.c index 64b7351..31fc213 100644 --- a/src/util.c +++ b/src/util.c @@ -108,7 +108,7 @@ setwinstate(Window win, long state) usage. {{{ */ void* -name_to_func(char *name, func_name_list_t l[]) +name_to_func(char *name, func_name_list_t *l) { int i; diff --git a/src/wmfs.c b/src/wmfs.c index 9d5b52b..fdb254e 100644 --- a/src/wmfs.c +++ b/src/wmfs.c @@ -107,6 +107,7 @@ quit(void) free(infobar); free(seltag); free(keys); + free(func_list); free(conf.ntag); free(conf.titlebar.mouse); free(conf.client.mouse); @@ -313,6 +314,8 @@ main(int argc, char **argv) XSetErrorHandler(errorhandler); /* Let's Go ! */ + + ewmh_init_hints(); init_conf(); init(); scan(); diff --git a/src/wmfs.h b/src/wmfs.h index 4ed01e3..924d42c 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -80,7 +80,7 @@ #define FRAMEH(h) h + (BORDH * 2) + TBARH #define RESHW 5 * BORDH #define CHECK(x) if(!x) return -#define ITOA(p ,n) sprintf(p, "%d", n) +#define LEN(x) (sizeof(x) / sizeof(x[0])) #define deb(p) fprintf(stderr, "debug: %d\n", p) #define PAD 14 @@ -157,7 +157,6 @@ void ewmh_set_desktop_geometry(void); void ewmh_set_workarea(void); void ewmh_manage_net_wm_state(long data_l[], Client *c); void ewmh_manage_window_type(Client *c); -long ewmh_get_wm_state(Window win); /* frame.c */ void frame_create(Client *c); @@ -203,7 +202,7 @@ void *emalloc(uint element, uint size); ulong getcolor(char *color); void setwinstate(Window win, long state); /* Conf usage {{{ */ -void* name_to_func(char *name, func_name_list_t l[]); +void* name_to_func(char *name, func_name_list_t *l); ulong char_to_modkey(char *name, key_name_list_t key_l[]); 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[]); @@ -297,6 +296,7 @@ Client *clients; Client *sel; /* Other */ +func_name_list_t *func_list; uint numlockmask; #endif /* WMFS_H */ diff --git a/wmfsrc b/wmfsrc index cb3a375..2253d69 100644 --- a/wmfsrc +++ b/wmfsrc @@ -82,8 +82,8 @@ client titlebar { height = 11 - fg_normal = "#003366" - fg_focus = "#7E89A2" + fg_normal = "#7E89A2" + fg_focus = "#9F9AB3" mouse { button = "1" func = "client_raise" } mouse { button = "1" func = "mouse_move" }