# Set this to the location of the X installation you want to compile against
XROOT = /usr/X11R6
-# Some flexibility for configuration location
-CONFPREFIX = $(PREFIX)
-CONFDIR = /etc/X11/windowlab
-
-# Set this to the location of the global configuration files
-SYSCONFDIR = $(CONFPREFIX)$(CONFDIR)
-
-# Uncomment for debugging info (abandon all hope, ye who enter here)
-#DEFINES += -DDEBUG
-
# --------------------------------------------------------------------
CC = cc
endif
BINDIR = $(DESTDIR)$(PREFIX)/bin
-MANDIR = $(DESTDIR)$(PREFIX)$(MANBASE)/man1
-CFGDIR = $(DESTDIR)$(SYSCONFDIR)
INCLUDES = -I$(XROOT)/include \
- -I$(XROOT)/include/freetype2
+ -I$(XROOT)/include/freetype2 \
+ -I/usr/include/freetype2
LDPATH = -L$(XROOT)/lib
LIBS = -lX11 -lXft
PROG = windowlab
-MANPAGE = windowlab.1x
OBJS = main.o events.o client.o new.o manage.o misc.o
HEADERS = windowlab.h
install: all
mkdir -p $(BINDIR) && install -m 755 -s $(PROG) $(BINDIR)
- mkdir -p $(MANDIR) && install -m 644 $(MANPAGE) $(MANDIR) && gzip -9vfn $(MANDIR)/$(MANPAGE)
- mkdir -p $(CFGDIR) && cp -i windowlab.menurc $(CFGDIR)/windowlab.menurc && chmod 644 $(CFGDIR)/windowlab.menurc
clean:
rm -f $(PROG) $(OBJS)
{
XftDrawString8(c->xftdraw, &xft_detail, xftfont, SPACE, SPACE + xftfont->ascent, (unsigned char *)c->name, strlen(c->name));
}
- if (c == focused_client)
- {
- draw_close_button(c, &text_gc, &active_gc);
- }
- else
- {
- draw_close_button(c, &text_gc, &inactive_gc);
- }
}
/* Window gravity is a mess to explain, but we don't need to do much
}
return prev_focused;
}
-
-void draw_close_button(Client *c, GC *detail_gc, GC *background_gc)
-{
- int x, topleft_offset;
- x = c->width - (BARHEIGHT() - DEF_BORDERWIDTH);
- topleft_offset = (BARHEIGHT() / 2) - 5; // 5 being ~half of 9
- XFillRectangle(dsply, c->frame, *background_gc, x, 0, BARHEIGHT() - DEF_BORDERWIDTH, BARHEIGHT() - DEF_BORDERWIDTH);
-
- XDrawLine(dsply, c->frame, *detail_gc, x + topleft_offset + 1, topleft_offset, x + topleft_offset + 8, topleft_offset + 7);
- XDrawLine(dsply, c->frame, *detail_gc, x + topleft_offset + 1, topleft_offset + 1, x + topleft_offset + 7, topleft_offset + 7);
- XDrawLine(dsply, c->frame, *detail_gc, x + topleft_offset, topleft_offset + 1, x + topleft_offset + 7, topleft_offset + 8);
-
- XDrawLine(dsply, c->frame, *detail_gc, x + topleft_offset, topleft_offset + 7, x + topleft_offset + 7, topleft_offset);
- XDrawLine(dsply, c->frame, *detail_gc, x + topleft_offset + 1, topleft_offset + 7, x + topleft_offset + 7, topleft_offset + 1);
- XDrawLine(dsply, c->frame, *detail_gc, x + topleft_offset + 1, topleft_offset + 8, x + topleft_offset + 8, topleft_offset + 1);
-}
*/
#include <X11/Xatom.h>
+#include <sys/select.h>
#include "windowlab.h"
static void handle_button_press(XButtonEvent *);
static void handle_windowbar_click(XButtonEvent *, Client *);
-static unsigned int box_clicked(Client *, int);
-static void draw_button(Client *, GC *, GC *, unsigned int);
static void handle_configure_request(XConfigureRequestEvent *);
static void handle_map_request(XMapRequestEvent *);
static void handle_unmap_event(XUnmapEvent *);
void do_event_loop(void)
{
XEvent ev;
-
for (;;)
{
interruptible_XNextEvent(&ev);
{
Client *c;
- if (e->state & MODIFIER)
- {
- if (focused_client != NULL)
- resize(focused_client, e->x_root, e->y_root);
- else // pass event on
- XAllowEvents(dsply, ReplayPointer, CurrentTime);
- }
- 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())
- {
- handle_windowbar_click(e, c);
- }
- }
+ // 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())
+ handle_windowbar_click(e, 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;
- }
- }
- }
- 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()
- * from the right hand side. We only care about 0, 1 and 2. */
-
-static unsigned int box_clicked(Client *c, int x)
-{
- int pix_from_right = c->width - x;
- if (pix_from_right < 0)
+ if (first_click_c == c && (e->time - first_click_time) < DEF_DBLCLKTIME)
{
- return UINT_MAX; // outside window
+ raise_lower(c);
+ first_click_c = NULL; // prevent 3rd clicks counting as double clicks
}
else
{
- return (pix_from_right / (BARHEIGHT() - DEF_BORDERWIDTH));
+ first_click_c = c;
}
-}
-
-static void draw_button(Client *c, GC *detail_gc, GC *background_gc, unsigned int which_box)
-{
- if (which_box == 0)
- draw_close_button(c, detail_gc, background_gc);
+ first_click_time = e->time;
+ move(c);
}
/* Because we are redirecting the root window, we get ConfigureRequest
{
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.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.width = e->width;
wc.height = e->height;
- //wc.sibling = e->above;
- //wc.stack_mode = e->detail;
XConfigureWindow(dsply, e->window, e->value_mask, &wc);
}
static void handle_map_request(XMapRequestEvent *e)
{
- Client *c = find_client(e->window, WINDOW);
- if (c != NULL)
- {
- }
- else
- {
+ if (!find_client(e->window, WINDOW))
make_new_client(e->window);
- }
}
/* See windowlab.h for the intro to this one. If this is a window we
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
+#define _POSIX_C_SOURCE 200809L
#include <string.h>
#include <signal.h>
#include <X11/cursorfont.h>
XDestroyWindow(dsply, constraint_win);
}
-void resize(Client *c, int x, int y)
-{
- XEvent ev;
- Client *exposed_c;
- Rect newdims, recalceddims, bounddims;
- unsigned int dragging_outwards, dw, dh;
- Window constraint_win, resize_win, resizebar_win;
- XSetWindowAttributes pattr, resize_pattr, resizebar_pattr;
-
- if (x > c->x + BORDERWIDTH(c) && x < (c->x + c->width) - BORDERWIDTH(c) && y > (c->y - BARHEIGHT()) + BORDERWIDTH(c) && y < (c->y + c->height) - BORDERWIDTH(c))
- {
- // inside the window, dragging outwards
- dragging_outwards = 1;
- }
- else
- {
- // outside the window, dragging inwards
- dragging_outwards = 0;
- }
-
- dw = DisplayWidth(dsply, screen);
- dh = DisplayHeight(dsply, screen);
-
- bounddims.x = 0;
- bounddims.width = dw;
- bounddims.y = 0;
- bounddims.height = dh;
-
- 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, resize_curs, CurrentTime) == GrabSuccess))
- {
- XDestroyWindow(dsply, constraint_win);
- return;
- }
-
- newdims.x = c->x;
- newdims.y = c->y - BARHEIGHT();
- newdims.width = c->width;
- newdims.height = c->height + BARHEIGHT();
-
- copy_dims(&newdims, &recalceddims);
-
- // create and map resize window
- resize_pattr.override_redirect = True;
- resize_pattr.event_mask = ChildMask|ButtonPressMask|ExposureMask|EnterWindowMask;
- resize_win = XCreateWindow(dsply, root, newdims.x, newdims.y, newdims.width, newdims.height, DEF_BORDERWIDTH, DefaultDepth(dsply, screen), CopyFromParent, DefaultVisual(dsply, screen), CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWEventMask, &resize_pattr);
- XMapRaised(dsply, resize_win);
-
- resizebar_pattr.override_redirect = True;
- resizebar_pattr.background_pixel = active_col.pixel;
- resizebar_pattr.border_pixel = border_col.pixel;
- resizebar_pattr.event_mask = ChildMask|ButtonPressMask|ExposureMask|EnterWindowMask;
- resizebar_win = XCreateWindow(dsply, resize_win, -DEF_BORDERWIDTH, -DEF_BORDERWIDTH, newdims.width, BARHEIGHT() - DEF_BORDERWIDTH, DEF_BORDERWIDTH, DefaultDepth(dsply, screen), CopyFromParent, DefaultVisual(dsply, screen), CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWEventMask, &resizebar_pattr);
- XMapRaised(dsply, resizebar_win);
-
- // temporarily swap drawables in order to draw on the resize window's XFT context
- XftDrawChange(c->xftdraw, (Drawable) resizebar_win);
-
- // hide real window's frame
- XUnmapWindow(dsply, c->frame);
-
- do
- {
- XMaskEvent(dsply, ExposureMask|MouseMask, &ev);
- switch (ev.type)
- {
- case Expose:
- if (ev.xexpose.window == resizebar_win)
- {
- write_titletext(c, resizebar_win);
- }
- else
- {
- exposed_c = find_client(ev.xexpose.window, FRAME);
- if (exposed_c)
- {
- redraw(exposed_c);
- }
- }
- break;
- }
- }
- while (ev.type != ButtonRelease);
-
- XUngrabServer(dsply);
- ungrab();
- c->x = recalceddims.x;
- c->y = recalceddims.y + BARHEIGHT();
- c->width = recalceddims.width;
- c->height = recalceddims.height - BARHEIGHT();
-
- XMoveResizeWindow(dsply, c->frame, c->x, c->y - BARHEIGHT(), c->width, c->height + BARHEIGHT());
- XResizeWindow(dsply, c->window, c->width, c->height);
-
- // unhide real window's frame
- XMapWindow(dsply, c->frame);
-
- XSetInputFocus(dsply, c->window, RevertToNone, CurrentTime);
-
- send_config(c);
- XDestroyWindow(dsply, constraint_win);
-
- // reset the drawable
- XftDrawChange(c->xftdraw, (Drawable) c->frame);
-
- XDestroyWindow(dsply, resizebar_win);
- XDestroyWindow(dsply, resize_win);
-}
-
void write_titletext(Client *c, Window bar_win)
{
if (!c->trans && c->name != NULL)