void do_event_loop(void)
{
- XEvent ev;
+ XEvent ev;
- for (;;)
- {
- interruptible_XNextEvent(&ev);
+ for (;;)
+ {
+ interruptible_XNextEvent(&ev);
#ifdef DEBUG
- show_event(ev);
+ show_event(ev);
#endif
- /* check to see if menu rebuild has been requested */
- if (do_menuitems)
- {
- free_menuitems();
- get_menuitems();
- }
-
- switch (ev.type)
- {
- case KeyPress:
- handle_key_press(&ev.xkey);
- break;
- case ButtonPress:
- handle_button_press(&ev.xbutton);
- break;
- case ConfigureRequest:
- handle_configure_request(&ev.xconfigurerequest);
- break;
- case MapRequest:
- handle_map_request(&ev.xmaprequest);
- break;
- case UnmapNotify:
- handle_unmap_event(&ev.xunmap);
- break;
- case DestroyNotify:
- handle_destroy_event(&ev.xdestroywindow);
- break;
- case ClientMessage:
- handle_client_message(&ev.xclient);
- break;
- case ColormapNotify:
- handle_colormap_change(&ev.xcolormap);
- break;
- case PropertyNotify:
- handle_property_change(&ev.xproperty);
- break;
- case EnterNotify:
- handle_enter_event(&ev.xcrossing);
- break;
- case Expose:
- handle_expose_event(&ev.xexpose);
- break;
- }
- }
+ switch (ev.type)
+ {
+ case KeyPress:
+ handle_key_press(&ev.xkey);
+ break;
+ case ButtonPress:
+ handle_button_press(&ev.xbutton);
+ break;
+ case ConfigureRequest:
+ handle_configure_request(&ev.xconfigurerequest);
+ break;
+ case MapRequest:
+ handle_map_request(&ev.xmaprequest);
+ break;
+ case UnmapNotify:
+ handle_unmap_event(&ev.xunmap);
+ break;
+ case DestroyNotify:
+ handle_destroy_event(&ev.xdestroywindow);
+ break;
+ case ClientMessage:
+ handle_client_message(&ev.xclient);
+ break;
+ case ColormapNotify:
+ handle_colormap_change(&ev.xcolormap);
+ break;
+ case PropertyNotify:
+ handle_property_change(&ev.xproperty);
+ break;
+ case EnterNotify:
+ handle_enter_event(&ev.xcrossing);
+ break;
+ case Expose:
+ handle_expose_event(&ev.xexpose);
+ break;
+ }
+ }
}
static void handle_key_press(XKeyEvent *e)
{
- KeySym key = XKeycodeToKeysym(dsply, e->keycode, 0);
- switch (key)
- {
- case KEY_CYCLEPREV:
- cycle_previous();
- break;
- case KEY_CYCLENEXT:
- cycle_next();
- break;
- case KEY_FULLSCREEN:
- toggle_fullscreen(focused_client);
- break;
- case KEY_TOGGLEZ:
- raise_lower(focused_client);
- break;
- }
+ KeySym key = XKeycodeToKeysym(dsply, e->keycode, 0);
+ switch (key)
+ {
+ case KEY_CYCLEPREV:
+ cycle_previous();
+ break;
+ case KEY_CYCLENEXT:
+ cycle_next();
+ break;
+ case KEY_FULLSCREEN:
+ toggle_fullscreen(focused_client);
+ break;
+ case KEY_TOGGLEZ:
+ raise_lower(focused_client);
+ break;
+ }
}
/* Someone clicked a button. If it was on the root, we get the click
static void handle_button_press(XButtonEvent *e)
{
- Client *c;
-
- if (e->state & MODIFIER)
- {
- if (focused_client != NULL && focused_client != fullscreen_client)
- {
- resize(focused_client, e->x_root, e->y_root);
- }
- else
- {
- // pass event on
- XAllowEvents(dsply, ReplayPointer, CurrentTime);
- }
- }
- else if (e->window == root)
- {
+ Client *c;
+
+ if (e->state & MODIFIER)
+ {
+ if (focused_client != NULL && focused_client != fullscreen_client)
+ {
+ resize(focused_client, e->x_root, e->y_root);
+ }
+ else
+ {
+ // pass event on
+ XAllowEvents(dsply, ReplayPointer, CurrentTime);
+ }
+ }
+ else if (e->window == root)
+ {
#ifdef DEBUG
- dump_clients();
+ dump_clients();
#endif
- if (e->button == Button3)
- {
- rclick_root();
- }
- }
- else if (e->window == taskbar)
- {
- switch (e->button)
- {
- case Button1: // left mouse button
- lclick_taskbar(e->x);
- break;
- case Button3: // right mouse button
- rclick_taskbar(e->x);
- break;
- case Button4: // mouse wheel up
- cycle_previous();
- break;
- case Button5: // mouse wheel down
- cycle_next();
- break;
- }
- }
- else
- {
- // pass event on
- XAllowEvents(dsply, ReplayPointer, CurrentTime);
- if (e->button == Button1)
- {
- c = find_client(e->window, FRAME);
- if (c != NULL)
- {
- // click-to-focus
- check_focus(c);
- if (e->y < BARHEIGHT() && c != fullscreen_client)
- {
- handle_windowbar_click(e, c);
- }
- }
- }
- else if (e->button == Button3)
- {
- rclick_root();
- }
- }
+ }
+ else if (e->window == taskbar)
+ {
+ switch (e->button)
+ {
+ case Button1: // left mouse button
+ lclick_taskbar(e->x);
+ break;
+ case Button4: // mouse wheel up
+ cycle_previous();
+ break;
+ case Button5: // mouse wheel down
+ cycle_next();
+ break;
+ }
+ }
+ else
+ {
+ // pass event on
+ XAllowEvents(dsply, ReplayPointer, CurrentTime);
+ if (e->button == Button1)
+ {
+ c = find_client(e->window, FRAME);
+ if (c != NULL)
+ {
+ // click-to-focus
+ check_focus(c);
+ if (e->y < BARHEIGHT() && c != fullscreen_client)
+ {
+ handle_windowbar_click(e, c);
+ }
+ }
+ }
+ }
}
static void handle_windowbar_click(XButtonEvent *e, Client *c)
{
- static Client * first_click_c;
- static Time first_click_time;
- unsigned int in_box, in_box_down, in_box_up;
- int win_ypos;
- XEvent ev;
-
- in_box_down = box_clicked(c, e->x);
- if (in_box_down <= 2)
- {
- if (!grab(root, MouseMask, None))
- {
- return;
- }
-
- XGrabServer(dsply);
-
- in_box = 1;
-
- draw_button(c, &text_gc, &depressed_gc, in_box_down);
-
- do
- {
- XMaskEvent(dsply, MouseMask, &ev);
- in_box_up = box_clicked(c, ev.xbutton.x - (c->x + DEF_BORDERWIDTH));
- win_ypos = (ev.xbutton.y - c->y) + BARHEIGHT();
- if (ev.type == MotionNotify)
- {
- if ((win_ypos <= BARHEIGHT()) && (win_ypos >= DEF_BORDERWIDTH) && (in_box_up == in_box_down))
- {
- in_box = 1;
- draw_button(c, &text_gc, &depressed_gc, in_box_down);
- }
- else
- {
- in_box = 0;
- draw_button(c, &text_gc, &active_gc, in_box_down);
- }
- }
- }
- while (ev.type != ButtonRelease);
- draw_button(c, &text_gc, &active_gc, in_box_down);
-
- XUngrabServer(dsply);
- ungrab();
- if (in_box)
- {
- switch (in_box_up)
- {
- case 0:
- send_wm_delete(c);
- break;
- case 1:
- raise_lower(c);
- break;
- case 2:
- hide(c);
- break;
- }
- }
- }
- else if (in_box_down != UINT_MAX)
- {
- if (first_click_c == c && (e->time - first_click_time) < DEF_DBLCLKTIME)
- {
- raise_lower(c);
- first_click_c = NULL; // prevent 3rd clicks counting as double clicks
- }
- else
- {
- first_click_c = c;
- }
- first_click_time = e->time;
- move(c);
- }
+ static Client * first_click_c;
+ static Time first_click_time;
+ unsigned int in_box, in_box_down, in_box_up;
+ int win_ypos;
+ XEvent ev;
+
+ in_box_down = box_clicked(c, e->x);
+ if (in_box_down <= 2)
+ {
+ if (!grab(root, MouseMask, None))
+ {
+ return;
+ }
+
+ XGrabServer(dsply);
+
+ in_box = 1;
+
+ draw_button(c, &text_gc, &depressed_gc, in_box_down);
+
+ do
+ {
+ XMaskEvent(dsply, MouseMask, &ev);
+ in_box_up = box_clicked(c, ev.xbutton.x - (c->x + DEF_BORDERWIDTH));
+ win_ypos = (ev.xbutton.y - c->y) + BARHEIGHT();
+ if (ev.type == MotionNotify)
+ {
+ if ((win_ypos <= BARHEIGHT()) && (win_ypos >= DEF_BORDERWIDTH) && (in_box_up == in_box_down))
+ {
+ in_box = 1;
+ draw_button(c, &text_gc, &depressed_gc, in_box_down);
+ }
+ else
+ {
+ in_box = 0;
+ draw_button(c, &text_gc, &active_gc, in_box_down);
+ }
+ }
+ }
+ while (ev.type != ButtonRelease);
+ draw_button(c, &text_gc, &active_gc, in_box_down);
+
+ XUngrabServer(dsply);
+ ungrab();
+ if (in_box)
+ {
+ switch (in_box_up)
+ {
+ case 0:
+ send_wm_delete(c);
+ break;
+ case 1:
+ raise_lower(c);
+ break;
+ case 2:
+ hide(c);
+ break;
+ }
+ }
+ }
+ else if (in_box_down != UINT_MAX)
+ {
+ if (first_click_c == c && (e->time - first_click_time) < DEF_DBLCLKTIME)
+ {
+ raise_lower(c);
+ first_click_c = NULL; // prevent 3rd clicks counting as double clicks
+ }
+ else
+ {
+ first_click_c = c;
+ }
+ first_click_time = e->time;
+ move(c);
+ }
}
/* Return which button was clicked - this is a multiple of BARHEIGHT()
static unsigned int box_clicked(Client *c, int x)
{
- int pix_from_right = c->width - x;
- if (pix_from_right < 0)
- {
- return UINT_MAX; // outside window
- }
- else
- {
- return (pix_from_right / (BARHEIGHT() - DEF_BORDERWIDTH));
- }
+ int pix_from_right = c->width - x;
+ if (pix_from_right < 0)
+ {
+ return UINT_MAX; // outside window
+ }
+ else
+ {
+ return (pix_from_right / (BARHEIGHT() - DEF_BORDERWIDTH));
+ }
}
static void draw_button(Client *c, GC *detail_gc, GC *background_gc, unsigned int which_box)
{
- switch (which_box)
- {
- case 0:
- draw_close_button(c, detail_gc, background_gc);
- break;
- case 1:
- draw_toggledepth_button(c, detail_gc, background_gc);
- break;
- case 2:
- draw_hide_button(c, detail_gc, background_gc);
- break;
- }
+ switch (which_box)
+ {
+ case 0:
+ draw_close_button(c, detail_gc, background_gc);
+ break;
+ case 1:
+ draw_toggledepth_button(c, detail_gc, background_gc);
+ break;
+ case 2:
+ draw_hide_button(c, detail_gc, background_gc);
+ break;
+ }
}
/* Because we are redirecting the root window, we get ConfigureRequest
static void handle_configure_request(XConfigureRequestEvent *e)
{
- Client *c = find_client(e->window, WINDOW);
- XWindowChanges wc;
-
- if (fullscreen_client != NULL && c == fullscreen_client)
- {
- if (e->value_mask & CWX)
- {
- fs_prevdims.x = e->x;
- }
- if (e->value_mask & CWY)
- {
- fs_prevdims.y = e->y;
- }
- if (e->value_mask & CWWidth)
- {
- fs_prevdims.width = e->width;
- }
- if (e->value_mask & CWHeight)
- {
- fs_prevdims.height = e->height;
- }
- return;
- }
-
- if (c != NULL)
- {
- gravitate(c, REMOVE_GRAVITY);
- if (e->value_mask & CWX)
- {
- c->x = e->x;
- }
- if (e->value_mask & CWY)
- {
- c->y = e->y;
- }
- if (e->value_mask & CWWidth)
- {
- c->width = e->width;
- }
- if (e->value_mask & CWHeight)
- {
- c->height = e->height;
- }
- refix_position(c, e);
- gravitate(c, APPLY_GRAVITY);
- // configure the frame
- wc.x = c->x;
- wc.y = c->y - BARHEIGHT();
- wc.width = c->width;
- wc.height = c->height + BARHEIGHT();
- wc.border_width = DEF_BORDERWIDTH;
- //wc.sibling = e->above;
- //wc.stack_mode = e->detail;
- XConfigureWindow(dsply, c->frame, e->value_mask, &wc);
- send_config(c);
- // start setting up the next call
- wc.x = 0;
- wc.y = BARHEIGHT();
- }
- else
- {
- wc.x = e->x;
- wc.y = e->y;
- }
-
- wc.width = e->width;
- wc.height = e->height;
- //wc.sibling = e->above;
- //wc.stack_mode = e->detail;
- XConfigureWindow(dsply, e->window, e->value_mask, &wc);
+ Client *c = find_client(e->window, WINDOW);
+ XWindowChanges wc;
+
+ if (fullscreen_client != NULL && c == fullscreen_client)
+ {
+ if (e->value_mask & CWX)
+ {
+ fs_prevdims.x = e->x;
+ }
+ if (e->value_mask & CWY)
+ {
+ fs_prevdims.y = e->y;
+ }
+ if (e->value_mask & CWWidth)
+ {
+ fs_prevdims.width = e->width;
+ }
+ if (e->value_mask & CWHeight)
+ {
+ fs_prevdims.height = e->height;
+ }
+ return;
+ }
+
+ if (c != NULL)
+ {
+ gravitate(c, REMOVE_GRAVITY);
+ if (e->value_mask & CWX)
+ {
+ c->x = e->x;
+ }
+ if (e->value_mask & CWY)
+ {
+ c->y = e->y;
+ }
+ if (e->value_mask & CWWidth)
+ {
+ c->width = e->width;
+ }
+ if (e->value_mask & CWHeight)
+ {
+ c->height = e->height;
+ }
+ refix_position(c, e);
+ gravitate(c, APPLY_GRAVITY);
+ // configure the frame
+ wc.x = c->x;
+ wc.y = c->y - BARHEIGHT();
+ wc.width = c->width;
+ wc.height = c->height + BARHEIGHT();
+ wc.border_width = DEF_BORDERWIDTH;
+ //wc.sibling = e->above;
+ //wc.stack_mode = e->detail;
+ XConfigureWindow(dsply, c->frame, e->value_mask, &wc);
+ send_config(c);
+ // start setting up the next call
+ wc.x = 0;
+ wc.y = BARHEIGHT();
+ }
+ else
+ {
+ wc.x = e->x;
+ wc.y = e->y;
+ }
+
+ wc.width = e->width;
+ wc.height = e->height;
+ //wc.sibling = e->above;
+ //wc.stack_mode = e->detail;
+ XConfigureWindow(dsply, e->window, e->value_mask, &wc);
}
/* Two possibilities if a client is asking to be mapped. One is that
static void handle_map_request(XMapRequestEvent *e)
{
- Client *c = find_client(e->window, WINDOW);
- if (c != NULL)
- {
- unhide(c);
- }
- else
- {
- make_new_client(e->window);
- }
+ Client *c = find_client(e->window, WINDOW);
+ if (c != NULL)
+ {
+ unhide(c);
+ }
+ else
+ {
+ make_new_client(e->window);
+ }
}
/* See windowlab.h for the intro to this one. If this is a window we
static void handle_unmap_event(XUnmapEvent *e)
{
- Client *c = find_client(e->window, WINDOW);
-
- if (c != NULL)
- {
- if (c->ignore_unmap)
- {
- c->ignore_unmap--;
- }
- else
- {
- remove_client(c, WITHDRAW);
- }
- }
+ Client *c = find_client(e->window, WINDOW);
+
+ if (c != NULL)
+ {
+ if (c->ignore_unmap)
+ {
+ c->ignore_unmap--;
+ }
+ else
+ {
+ remove_client(c, WITHDRAW);
+ }
+ }
}
/* This happens when a window is iconified and destroys itself. An
static void handle_destroy_event(XDestroyWindowEvent *e)
{
- Client *c = find_client(e->window, WINDOW);
- if (c != NULL)
- {
- remove_client(c, WITHDRAW);
- }
+ Client *c = find_client(e->window, WINDOW);
+ if (c != NULL)
+ {
+ remove_client(c, WITHDRAW);
+ }
}
/* If a client wants to iconify itself (boo! hiss!) it must send a
static void handle_client_message(XClientMessageEvent *e)
{
- Client *c = find_client(e->window, WINDOW);
- if (c != NULL && e->message_type == wm_change_state && e->format == 32 && e->data.l[0] == IconicState)
- {
- hide(c);
- }
+ Client *c = find_client(e->window, WINDOW);
+ if (c != NULL && e->message_type == wm_change_state && e->format == 32 && e->data.l[0] == IconicState)
+ {
+ hide(c);
+ }
}
/* All that we have cached is the name and the size hints, so we only
static void handle_property_change(XPropertyEvent *e)
{
- Client *c = find_client(e->window, WINDOW);
- long dummy;
-
- if (c != NULL)
- {
- switch (e->atom)
- {
- case XA_WM_NAME:
- if (c->name)
- {
- XFree(c->name);
- c->name = NULL;
- }
- XFetchName(dsply, c->window, &c->name);
- redraw(c);
- redraw_taskbar();
- break;
- case XA_WM_NORMAL_HINTS:
- XGetWMNormalHints(dsply, c->window, c->size, &dummy);
- break;
- }
- }
+ Client *c = find_client(e->window, WINDOW);
+ long dummy;
+
+ if (c != NULL)
+ {
+ switch (e->atom)
+ {
+ case XA_WM_NAME:
+ if (c->name)
+ {
+ XFree(c->name);
+ c->name = NULL;
+ }
+ XFetchName(dsply, c->window, &c->name);
+ redraw(c);
+ redraw_taskbar();
+ break;
+ case XA_WM_NORMAL_HINTS:
+ XGetWMNormalHints(dsply, c->window, c->size, &dummy);
+ break;
+ }
+ }
}
/* X's default focus policy is follows-mouse, but we have to set it
static void handle_enter_event(XCrossingEvent *e)
{
- Client *c = NULL;
- if (e->window == taskbar)
- {
- in_taskbar = 1;
- if (showing_taskbar == 0)
- {
- showing_taskbar = 1;
- redraw_taskbar();
- }
- }
- else
- {
- in_taskbar = 0;
- if (fullscreen_client != NULL)
- {
- if (showing_taskbar == 1)
- {
- showing_taskbar = 0;
- redraw_taskbar();
- }
- }
- else // no fullscreen client
- {
- if (showing_taskbar == 0)
- {
- showing_taskbar = 1;
- redraw_taskbar();
- }
- }
-
- c = find_client(e->window, FRAME);
- if (c != NULL)
- {
- XGrabButton(dsply, AnyButton, AnyModifier, c->frame, False, ButtonMask, GrabModeSync, GrabModeSync, None, None);
- }
- }
+ Client *c = NULL;
+ if (e->window == taskbar)
+ {
+ in_taskbar = 1;
+ if (showing_taskbar == 0)
+ {
+ showing_taskbar = 1;
+ redraw_taskbar();
+ }
+ }
+ else
+ {
+ in_taskbar = 0;
+ if (fullscreen_client != NULL)
+ {
+ if (showing_taskbar == 1)
+ {
+ showing_taskbar = 0;
+ redraw_taskbar();
+ }
+ }
+ else // no fullscreen client
+ {
+ if (showing_taskbar == 0)
+ {
+ showing_taskbar = 1;
+ redraw_taskbar();
+ }
+ }
+
+ c = find_client(e->window, FRAME);
+ if (c != NULL)
+ {
+ XGrabButton(dsply, AnyButton, AnyModifier, c->frame, False, ButtonMask, GrabModeSync, GrabModeSync, None, None);
+ }
+ }
}
/* Here's part 2 of our colormap policy: when a client installs a new
static void handle_colormap_change(XColormapEvent *e)
{
- Client *c = find_client(e->window, WINDOW);
- //if (c != NULL && e->c_new) // use c_new for c++
- if (c != NULL && e->new)
- {
- c->cmap = e->colormap;
- XInstallColormap(dsply, c->cmap);
- }
+ Client *c = find_client(e->window, WINDOW);
+ //if (c != NULL && e->c_new) // use c_new for c++
+ if (c != NULL && e->new)
+ {
+ c->cmap = e->colormap;
+ XInstallColormap(dsply, c->cmap);
+ }
}
/* If we were covered by multiple windows, we will usually get
static void handle_expose_event(XExposeEvent *e)
{
- if (e->window == taskbar)
- {
- if (e->count == 0)
- {
- redraw_taskbar();
- }
- }
- else
- {
- Client *c = find_client(e->window, FRAME);
- if (c != NULL && e->count == 0)
- {
- redraw(c);
- }
- }
+ if (e->window == taskbar)
+ {
+ if (e->count == 0)
+ {
+ redraw_taskbar();
+ }
+ }
+ else
+ {
+ Client *c = find_client(e->window, FRAME);
+ if (c != NULL && e->count == 0)
+ {
+ redraw(c);
+ }
+ }
}
/* interruptibleXNextEvent() was originally taken from Blender's source code
static int interruptible_XNextEvent(XEvent *event)
{
- fd_set fds;
- int rc;
- int dsply_fd = ConnectionNumber(dsply);
- for (;;)
- {
- if (XPending(dsply))
- {
- XNextEvent(dsply, event);
- return 1;
- }
- FD_ZERO(&fds);
- FD_SET(dsply_fd, &fds);
- rc = select(dsply_fd + 1, &fds, NULL, NULL, NULL);
- if (rc < 0)
- {
- if (errno == EINTR)
- {
- return 0;
- }
- return 1;
- }
- }
+ fd_set fds;
+ int rc;
+ int dsply_fd = ConnectionNumber(dsply);
+ for (;;)
+ {
+ if (XPending(dsply))
+ {
+ XNextEvent(dsply, event);
+ return 1;
+ }
+ FD_ZERO(&fds);
+ FD_SET(dsply_fd, &fds);
+ rc = select(dsply_fd + 1, &fds, NULL, NULL, NULL);
+ if (rc < 0)
+ {
+ if (errno == EINTR)
+ {
+ return 0;
+ }
+ return 1;
+ }
+ }
}
XFontStruct *font = NULL;
XftFont *xftfont = NULL;
XftColor xft_detail;
-GC string_gc, border_gc, text_gc, active_gc, depressed_gc, inactive_gc, menu_gc, selected_gc, empty_gc;
-XColor border_col, text_col, active_col, depressed_col, inactive_col, menu_col, selected_col, empty_col;
+GC string_gc, border_gc, text_gc, active_gc, depressed_gc, inactive_gc, selected_gc, empty_gc;
+XColor border_col, text_col, active_col, depressed_col, inactive_col, selected_col, empty_col;
Cursor resize_curs;
Atom wm_state, wm_change_state, wm_protos, wm_delete, wm_cmapwins;
Client *head_client = NULL, *focused_client = NULL, *topmost_client = NULL, *fullscreen_client = NULL;
char *opt_text = DEF_TEXT;
char *opt_active = DEF_ACTIVE;
char *opt_inactive = DEF_INACTIVE;
-char *opt_menu = DEF_MENU;
char *opt_selected = DEF_SELECTED;
char *opt_empty = DEF_EMPTY;
char *opt_display = NULL;
int main(int argc, char **argv)
{
- int i;
struct sigaction act;
-
-#define OPT_STR(name, variable) \
- if (strcmp(argv[i], name) == 0 && i + 1 < argc) \
- { \
- variable = argv[++i]; \
- continue; \
- }
-
- for (i = 1; i < argc; i++)
- {
- OPT_STR("-font", opt_font)
- OPT_STR("-border", opt_border)
- OPT_STR("-text", opt_text)
- OPT_STR("-active", opt_active)
- OPT_STR("-inactive", opt_inactive)
- OPT_STR("-menu", opt_menu)
- OPT_STR("-selected", opt_selected)
- OPT_STR("-empty", opt_empty)
- OPT_STR("-display", opt_display)
- if (strcmp(argv[i], "-about") == 0)
- {
- printf("WindowLab " VERSION " (" RELEASEDATE "), Copyright (c) 2001-2009 Nick Gravgaard\nWindowLab comes with ABSOLUTELY NO WARRANTY.\nThis is free software, and you are welcome to redistribute it\nunder certain conditions; view the LICENCE file for details.\n");
- exit(0);
- }
- // shouldn't get here; must be a bad option
- err("usage:\n windowlab [options]\n\noptions are:\n -font <font>\n -border|-text|-active|-inactive|-menu|-selected|-empty <color>\n -about\n -display <display>");
- return 2;
- }
-
act.sa_handler = sig_handler;
act.sa_flags = 0;
sigaction(SIGTERM, &act, NULL);
sigaction(SIGCHLD, &act, NULL);
setup_display();
- get_menuitems();
make_taskbar();
scan_wins();
do_event_loop();
- return 1; // just another brick in the -Wall
+ return 1;
}
static void scan_wins(void)
int i, j;
dsply = XOpenDisplay(opt_display);
-
if (dsply == NULL)
{
err("can't open display! check your DISPLAY variable.");
XAllocNamedColor(dsply, DefaultColormap(dsply, screen), opt_text, &text_col, &dummyc);
XAllocNamedColor(dsply, DefaultColormap(dsply, screen), opt_active, &active_col, &dummyc);
XAllocNamedColor(dsply, DefaultColormap(dsply, screen), opt_inactive, &inactive_col, &dummyc);
- XAllocNamedColor(dsply, DefaultColormap(dsply, screen), opt_menu, &menu_col, &dummyc);
XAllocNamedColor(dsply, DefaultColormap(dsply, screen), opt_selected, &selected_col, &dummyc);
XAllocNamedColor(dsply, DefaultColormap(dsply, screen), opt_empty, &empty_col, &dummyc);
gv.foreground = inactive_col.pixel;
inactive_gc = XCreateGC(dsply, root, GCFunction|GCForeground, &gv);
- gv.foreground = menu_col.pixel;
- menu_gc = XCreateGC(dsply, root, GCFunction|GCForeground, &gv);
-
gv.foreground = selected_col.pixel;
selected_gc = XCreateGC(dsply, root, GCFunction|GCForeground, &gv);
+++ /dev/null
-/* WindowLab - an X11 window manager
- * Copyright (c) 2001-2010 Nick Gravgaard
- * me at nickgravgaard.com
- * http://nickgravgaard.com/windowlab/
- *
- * 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 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "windowlab.h"
-
-// semaphor activated by SIGHUP
-int do_menuitems;
-
-static int parseline(char *, char *, char *);
-
-MenuItem *menuitems = NULL;
-unsigned int num_menuitems;
-XGlyphInfo extents;
-
-void get_menuitems(void)
-{
- unsigned int i, button_startx = 0;
- FILE *menufile = NULL;
- char menurcpath[PATH_MAX], *c;
- extern int errno;
-
- menuitems = (MenuItem *)malloc(MAX_MENUITEMS_SIZE);
- if (menuitems == NULL)
- {
- err("Unable to allocate menu items array.");
- return;
- }
- memset(menuitems, 0, MAX_MENUITEMS_SIZE);
-
- snprintf(menurcpath, sizeof(menurcpath), "%s/.windowlab/windowlab.menurc", getenv("HOME"));
-#ifdef DEBUG
- printf("trying to open: %s\n", menurcpath);
-#endif
- if ((menufile = fopen(menurcpath, "r")) == NULL)
- {
- ssize_t len;
- // get location of the executable
- if ((len = readlink("/proc/self/exe", menurcpath, PATH_MAX - 1)) == -1)
- {
- err("readlink() /proc/self/exe failed: %s\n", strerror(errno));
- menurcpath[0] = '.';
- menurcpath[1] = '\0';
- }
- else
- {
- // insert null to end the file path properly
- menurcpath[len] = '\0';
- }
- if ((c = strrchr(menurcpath, '/')) != NULL)
- {
- *c = '\0';
- }
- if ((c = strrchr(menurcpath, '/')) != NULL)
- {
- *c = '\0';
- }
- strncat(menurcpath, "/etc/windowlab.menurc", PATH_MAX - strlen(menurcpath) - 1);
-#ifdef DEBUG
- printf("trying to open: %s\n", menurcpath);
-#endif
- if ((menufile = fopen(menurcpath, "r")) == NULL)
- {
-#ifdef DEBUG
- printf("trying to open: %s\n", DEF_MENURC);
-#endif
- menufile = fopen(DEF_MENURC, "r");
- }
- }
- if (menufile != NULL)
- {
- num_menuitems = 0;
- while ((!feof(menufile)) && (!ferror(menufile)) && (num_menuitems < MAX_MENUITEMS))
- {
- char menustr[STR_SIZE] = "";
- fgets(menustr, STR_SIZE, menufile);
- if (strlen(menustr) != 0)
- {
- char *pmenustr = menustr;
- while (pmenustr[0] == ' ' || pmenustr[0] == '\t')
- {
- pmenustr++;
- }
- if (pmenustr[0] != '#')
- {
- char labelstr[STR_SIZE] = "", commandstr[STR_SIZE] = "";
- if (parseline(pmenustr, labelstr, commandstr))
- {
- menuitems[num_menuitems].label = (char *)malloc(strlen(labelstr) + 1);
- menuitems[num_menuitems].command = (char *)malloc(strlen(commandstr) + 1);
- strcpy(menuitems[num_menuitems].label, labelstr);
- strcpy(menuitems[num_menuitems].command, commandstr);
- num_menuitems++;
- }
- }
- }
- }
- fclose(menufile);
- }
- else
- {
- // one menu item - xterm
- err("can't find ~/.windowlab/windowlab.menurc, %s or %s\n", menurcpath, DEF_MENURC);
- menuitems[0].command = (char *)malloc(strlen(NO_MENU_COMMAND) + 1);
- strcpy(menuitems[0].command, NO_MENU_COMMAND);
- menuitems[0].label = (char *)malloc(strlen(NO_MENU_LABEL) + 1);
- strcpy(menuitems[0].label, NO_MENU_LABEL);
- num_menuitems = 1;
- }
-
- for (i = 0; i < num_menuitems; i++)
- {
- menuitems[i].x = button_startx;
- XftTextExtents8(dsply, xftfont, (unsigned char *)menuitems[i].label, strlen(menuitems[i].label), &extents);
- menuitems[i].width = extents.width + (SPACE * 4);
- button_startx += menuitems[i].width + 1;
- }
- // menu items have been built
- do_menuitems = 0;
-}
-
-int parseline(char *menustr, char *labelstr, char *commandstr)
-{
- int success = 0;
- int menustrlen = strlen(menustr);
- char *ptemp = NULL;
- char *menustrcpy = (char *)malloc(menustrlen + 1);
-
- if (menustrcpy == NULL)
- {
- return 0;
- }
-
- strcpy(menustrcpy, menustr);
- ptemp = strtok(menustrcpy, ":");
-
- if (ptemp != NULL)
- {
- strcpy(labelstr, ptemp);
- ptemp = strtok(NULL, "\n");
- if (ptemp != NULL) // right of ':' is not empty
- {
- while (*ptemp == ' ' || *ptemp == '\t')
- {
- ptemp++;
- }
- if (*ptemp != '\0' && *ptemp != '\r' && *ptemp != '\n')
- {
- strcpy(commandstr, ptemp);
- success = 1;
- }
- }
- }
- if (menustrcpy != NULL)
- {
- free(menustrcpy);
- }
- return success;
-}
-
-void free_menuitems(void)
-{
- unsigned int i;
- if (menuitems != NULL)
- {
- for (i = 0; i < num_menuitems; i++)
- {
- if (menuitems[i].label != NULL)
- {
- free(menuitems[i].label);
- menuitems[i].label = NULL;
- }
- if (menuitems[i].command != NULL)
- {
- free(menuitems[i].command);
- menuitems[i].command = NULL;
- }
- }
- free(menuitems);
- menuitems = NULL;
- }
-}
#include "windowlab.h"
-static void draw_menubar(void);
-static unsigned int update_menuitem(int);
-static void draw_menuitem(unsigned int, unsigned int);
-
Window taskbar;
XftDraw *tbxftdraw;
}
}
-void rclick_taskbar(int x)
-{
- XEvent ev;
- int mousex, mousey;
- Rect bounddims;
- unsigned int current_item = UINT_MAX;
- Window constraint_win;
- XSetWindowAttributes pattr;
-
- get_mouse_position(&mousex, &mousey);
-
- bounddims.x = 0;
- bounddims.y = 0;
- bounddims.width = DisplayWidth(dsply, screen);
- bounddims.height = BARHEIGHT();
-
- constraint_win = XCreateWindow(dsply, root, bounddims.x, bounddims.y, bounddims.width, bounddims.height, 0, CopyFromParent, InputOnly, CopyFromParent, 0, &pattr);
- XMapWindow(dsply, constraint_win);
-
- if (!(XGrabPointer(dsply, root, False, MouseMask, GrabModeAsync, GrabModeAsync, constraint_win, None, CurrentTime) == GrabSuccess))
- {
- XDestroyWindow(dsply, constraint_win);
- return;
- }
- draw_menubar();
- update_menuitem(INT_MAX); // force initial highlight
- current_item = update_menuitem(x);
- do
- {
- XMaskEvent(dsply, MouseMask|KeyMask, &ev);
- switch (ev.type)
- {
- case MotionNotify:
- current_item = update_menuitem(ev.xmotion.x);
- break;
- case ButtonRelease:
- if (current_item != UINT_MAX)
- {
- fork_exec(menuitems[current_item].command);
- }
- break;
- case KeyPress:
- XPutBackEvent(dsply, &ev);
- break;
- }
- }
- while (ev.type != ButtonPress && ev.type != ButtonRelease && ev.type != KeyPress);
-
- redraw_taskbar();
- XUnmapWindow(dsply, constraint_win);
- XDestroyWindow(dsply, constraint_win);
- ungrab();
-}
-
-void rclick_root(void)
-{
- XEvent ev;
- if (!grab(root, MouseMask, None))
- {
- return;
- }
- draw_menubar();
- do
- {
- XMaskEvent(dsply, MouseMask|KeyMask, &ev);
- switch (ev.type)
- {
- case MotionNotify:
- if (ev.xmotion.y < BARHEIGHT())
- {
- ungrab();
- rclick_taskbar(ev.xmotion.x);
- return;
- }
- break;
- case KeyPress:
- XPutBackEvent(dsply, &ev);
- break;
- }
- }
- while (ev.type != ButtonRelease && ev.type != KeyPress);
-
- redraw_taskbar();
- ungrab();
-}
-
void redraw_taskbar(void)
{
unsigned int i;
}
}
-void draw_menubar(void)
-{
- unsigned int i, dw;
- dw = DisplayWidth(dsply, screen);
- XFillRectangle(dsply, taskbar, menu_gc, 0, 0, dw, BARHEIGHT() - DEF_BORDERWIDTH);
-
- for (i = 0; i < num_menuitems; i++)
- {
- if (menuitems[i].label && menuitems[i].command)
- {
- XftDrawString8(tbxftdraw, &xft_detail, xftfont, menuitems[i].x + (SPACE * 2), xftfont->ascent + SPACE, (unsigned char *)menuitems[i].label, strlen(menuitems[i].label));
- }
- }
-}
-
-unsigned int update_menuitem(int mousex)
-{
- static unsigned int last_item; // retain value from last call
- unsigned int i;
- if (mousex == INT_MAX) // entered function to set last_item
- {
- last_item = num_menuitems;
- return UINT_MAX;
- }
- for (i = 0; i < num_menuitems; i++)
- {
- if ((mousex >= menuitems[i].x) && (mousex <= (menuitems[i].x + menuitems[i].width)))
- {
- break;
- }
- }
-
- if (i != last_item) // don't redraw if same
- {
- if (last_item != num_menuitems)
- {
- draw_menuitem(last_item, 0);
- }
- if (i != num_menuitems)
- {
- draw_menuitem(i, 1);
- }
- last_item = i; // set to new menu item
- }
-
- if (i != num_menuitems)
- {
- return i;
- }
- else // no item selected
- {
- return UINT_MAX;
- }
-}
-
-void draw_menuitem(unsigned int index, unsigned int active)
-{
- if (active)
- {
- XFillRectangle(dsply, taskbar, selected_gc, menuitems[index].x, 0, menuitems[index].width, BARHEIGHT() - DEF_BORDERWIDTH);
- }
- else
- {
- XFillRectangle(dsply, taskbar, menu_gc, menuitems[index].x, 0, menuitems[index].width, BARHEIGHT() - DEF_BORDERWIDTH);
- }
- XftDrawString8(tbxftdraw, &xft_detail, xftfont, menuitems[index].x + (SPACE * 2), xftfont->ascent + SPACE, (unsigned char *)menuitems[index].label, strlen(menuitems[index].label));
-}
-
float get_button_width(void)
{
unsigned int nwins = 0;