diff -aurBwbE pwm-20030617/clientwin.c pwm-20030617-shape/clientwin.c --- pwm-20030617/clientwin.c 2003-06-17 12:00:07.000000000 +0200 +++ pwm-20030617-shape/clientwin.c 2003-12-15 01:18:38.000000000 +0100 @@ -342,6 +342,13 @@ /* Unnecessary, done when reparenting */ /* XSelectInput(wglobal.dpy, win, cwin->event_mask); */ +#ifdef CF_SHAPE + cwin->is_shaped=0; + if (wglobal.has_shape){ + XShapeSelectInput(wglobal.dpy, win, ShapeNotifyMask); + } +#endif + XSaveContext(wglobal.dpy, win, wglobal.win_context, (XPointer)cwin); XAddToSaveSet(wglobal.dpy, win); @@ -960,4 +967,49 @@ } +#ifdef CF_SHAPE +bool set_client_shape(WClientWin *cwin, bool remove) +{ + int num, t; + XRectangle *sh; + WFrame *frame; + bool status = 0; + + if (cwin == NULL) + return 0; + + if (!WTHING_IS(cwin->t_parent,WTHING_FRAME)){ + fprintf(stderr,"Cannot set shape on non frame objects\n"); + return 0; + } + + frame = (WFrame *)cwin->t_parent; + + if (frame == NULL) + return 0; + + sh = XShapeGetRectangles(wglobal.dpy, cwin->client_win, ShapeBounding, &num, &t); + + if (num > 1) { + XShapeCombineShape(wglobal.dpy, frame->frame_win, ShapeBounding,0, 0, cwin->client_win, ShapeBounding, ShapeSet); + status = 1; + } else if (remove) { + XRectangle temp; + + temp.x = 0; + temp.y = 0; + temp.width = frame->frame_iw; + temp.height = frame->frame_ih; + + XShapeCombineRectangles(wglobal.dpy, frame->frame_win, ShapeBounding,0, 0, &temp, 1, ShapeSet, YXBanded); + } + + XFree(sh); + + return status; +} +#endif + + + /*}}}*/ diff -aurBwbE pwm-20030617/clientwin.h pwm-20030617-shape/clientwin.h --- pwm-20030617/clientwin.h 2003-05-28 23:55:08.000000000 +0200 +++ pwm-20030617-shape/clientwin.h 2003-12-09 11:09:35.000000000 +0100 @@ -12,6 +12,7 @@ #include "common.h" #include "thing.h" +#include "config.h" #define CWIN_DRAG 0x0001 #define CWIN_TAGGED 0x0002 @@ -56,6 +57,9 @@ struct _WClientWin *s_cwin_next; struct _WClientWin *s_cwin_prev; +#ifdef CF_SHAPE + bool is_shaped; +#endif } WClientWin; @@ -98,4 +102,8 @@ extern void clientwin_make_label(WClientWin *cwin, int maxw); extern char *clientwin_full_label(WClientWin *cwin); +#ifdef CF_SHAPE +bool set_client_shape(WClientWin *cwin, bool remove); +#endif + #endif /* INCLUDED_CLIENTWIN_H */ diff -aurBwbE pwm-20030617/common.h pwm-20030617-shape/common.h --- pwm-20030617/common.h 2003-05-28 23:55:08.000000000 +0200 +++ pwm-20030617-shape/common.h 2003-12-09 08:41:59.000000000 +0100 @@ -20,6 +20,10 @@ #include "global.h" #include "config.h" +#ifdef CF_SHAPE +#include +#endif + #define D(X) X; #endif /* INCLUDED_COMMON_H */ diff -aurBwbE pwm-20030617/config.h pwm-20030617-shape/config.h --- pwm-20030617/config.h 2003-05-28 23:55:08.000000000 +0200 +++ pwm-20030617-shape/config.h 2003-12-15 02:02:11.000000000 +0100 @@ -59,7 +59,7 @@ /*#define CF_NO_LOCK_HACK*/ /*#define CF_NO_MWM_HINTS*/ /*#define CF_NO_AUTOFOCUS*/ -/*#define CF_AUTOFOCUS_ALL*/ +#define CF_AUTOFOCUS_ALL /*#define CF_CWIN_TOPLEFT*/ /*#define CF_IGNORE_NONTRANSIENT_LOCATION*/ /*#define CF_NO_NUMBERING*/ @@ -164,4 +164,9 @@ #define SCROLL_AMOUNT 4 #define SCROLL_BORDER 4 +/* Extenssions + */ + +#define CF_SHAPE + #endif /* INCLUDED_CONFIG_H */ diff -aurBwbE pwm-20030617/draw.c pwm-20030617-shape/draw.c --- pwm-20030617/draw.c 2003-05-28 23:55:08.000000000 +0200 +++ pwm-20030617-shape/draw.c 2003-12-15 02:07:39.000000000 +0100 @@ -232,6 +232,9 @@ int fw, off, w, h; #endif + if(WFRAME_IS_NO_BAR(frame)) + return; + if((WWinObj*)frame==wglobal.current_winobj) colors=&(grdata->act_base_colors); else @@ -250,7 +253,6 @@ h=FRAME_H(frame)-CF_BEVEL_WIDTH*2; XSetForeground(wglobal.dpy, grdata->gc, colors->pixels[WCG_PIX_BG]); - /* top */ XFillRectangle(wglobal.dpy, frame->frame_win, grdata->gc, off, off, w, fw); diff -aurBwbE pwm-20030617/event.c pwm-20030617-shape/event.c --- pwm-20030617/event.c 2003-05-28 23:55:08.000000000 +0200 +++ pwm-20030617-shape/event.c 2003-12-15 02:06:01.000000000 +0100 @@ -42,7 +42,9 @@ static void handle_colormap_notify(const XColormapEvent *ev); static void pointer_handler(XEvent *ev); static void keyboard_handler(); - +#ifdef CF_SHAPE +static void handle_shape(XEvent *ev); +#endif /* */ @@ -105,6 +107,7 @@ void handle_event(XEvent *ev) { + switch(ev->type){ CASE_EVENT(MapRequest) handle_map_request(&(ev->xmaprequest)); @@ -159,6 +162,10 @@ CASE_EVENT(ReparentNotify) break; #endif default: +#ifdef CF_SHAPE + if (wglobal.has_shape && (ev->type == wglobal.shape_event_base)) + handle_shape(ev); +#endif break; } } @@ -297,6 +305,10 @@ if((ev->value_mask&(CWWidth|CWHeight))!=0) set_clientwin_size(cwin, ev->width, ev->height); +#ifdef CF_SHAPE + if((ev->value_mask&(CWWidth|CWHeight))!=0) + cwin->is_shaped = set_client_shape(cwin, cwin->is_shaped); +#endif #ifndef CF_NO_WILD_WINDOWS if((ev->value_mask&(CWX|CWY))!=0) @@ -314,6 +326,20 @@ raise_winobj(wglobal.current_winobj); } +#ifdef CF_SHAPE +static void handle_shape(XEvent *ev) +{ + WClientWin *cwin; + + cwin=find_clientwin(ev->xany.window); + if (cwin == NULL) + return; + + if (WTHING_IS(cwin->t_parent,WTHING_FRAME)){ + cwin->is_shaped = set_client_shape(cwin, cwin->is_shaped); + } +} +#endif /* */ @@ -362,6 +388,12 @@ } } + if (wglobal.skip_enter){ + /* Workspace has changed, do not set focus to the window the pointer is on */ + wglobal.skip_enter = 0; + return; + } + do_set_focus(thing); #if 0 set_timer(1000, autoraise_handler); diff -aurBwbE pwm-20030617/focus.c pwm-20030617-shape/focus.c --- pwm-20030617/focus.c 2003-05-28 23:55:08.000000000 +0200 +++ pwm-20030617-shape/focus.c 2003-12-08 11:51:45.000000000 +0100 @@ -58,6 +58,7 @@ return; } + wglobal.last_on_workspace[SCREEN->current_workspace] = thing; XSetInputFocus(wglobal.dpy, win, RevertToParent, CurrentTime); if(cwin!=NULL && cwin->flags&CWIN_P_WM_TAKE_FOCUS) diff -aurBwbE pwm-20030617/frame.c pwm-20030617-shape/frame.c --- pwm-20030617/frame.c 2003-05-28 23:55:08.000000000 +0200 +++ pwm-20030617-shape/frame.c 2003-12-15 01:19:47.000000000 +0100 @@ -302,8 +302,19 @@ void activate_frame(WFrame *frame) { +#ifdef CF_SHAPE + WClientWin *cwin; + cwin = (WClientWin *) frame->t_children; + + if (!cwin){ + return; + } + if (wglobal.has_shape) + cwin->is_shaped = set_client_shape(cwin, cwin->is_shaped); +#endif draw_frame_bar(frame, TRUE); draw_frame_frame(frame, TRUE); + } diff -aurBwbE pwm-20030617/global.h pwm-20030617-shape/global.h --- pwm-20030617/global.h 2003-05-28 23:55:08.000000000 +0200 +++ pwm-20030617-shape/global.h 2003-12-09 08:56:07.000000000 +0100 @@ -19,6 +19,7 @@ #include "winobj.h" #include "menu.h" #include "draw.h" +#include "config.h" #define MAX_SCREENS 1 @@ -65,6 +66,13 @@ int input_mode; Time dblclick_delay; + WThing ** last_on_workspace; + bool skip_enter; + +#ifdef CF_SHAPE + bool has_shape; + int shape_event_base; +#endif } WGlobal; extern WGlobal wglobal; diff -aurBwbE pwm-20030617/main.c pwm-20030617-shape/main.c --- pwm-20030617/main.c 2003-05-28 23:55:08.000000000 +0200 +++ pwm-20030617-shape/main.c 2003-12-15 01:20:04.000000000 +0100 @@ -143,7 +143,7 @@ bool onescreen) { Display *dpy; - int scr, i, nscr; + int scr, i, nscr, dummy; /* Open the display. */ dpy=XOpenDisplay(display); @@ -193,6 +193,10 @@ wglobal.conn=ConnectionNumber(dpy); wglobal.win_context=XUniqueContext(); +#ifdef CF_SHAPE + wglobal.has_shape = XShapeQueryExtension(dpy, &wglobal.shape_event_base, &dummy); +#endif + wglobal.atom_wm_state=XInternAtom(dpy, "WM_STATE", False); wglobal.atom_wm_change_state=XInternAtom(dpy, "WM_CHANGE_STATE", False); wglobal.atom_wm_protocols=XInternAtom(dpy, "WM_PROTOCOLS", False); @@ -216,6 +220,10 @@ return FALSE; read_config(cfgfile); + + if (!(wglobal.last_on_workspace = malloczero(SCREEN->n_workspaces * sizeof(WThing *)))) + die("No more memory"); + postinit_screen(); /*atexit(deinit);*/ diff -aurBwbE pwm-20030617/Makefile pwm-20030617-shape/Makefile --- pwm-20030617/Makefile 2003-06-17 19:32:22.000000000 +0200 +++ pwm-20030617-shape/Makefile 2003-12-09 08:58:40.000000000 +0100 @@ -8,7 +8,7 @@ ###################################### SUBDIRS=libtu -LIBS += -L./libtu -ltu -lm $(X11_LIBS) -lX11 +LIBS += -L./libtu -ltu -lm $(X11_LIBS) -lX11 -lXext INCLUDES += -I./libtu/include $(X11_INCLUDES) DEFINES += -DETCDIR=\"$(ETCDIR)\" CFLAGS += $(XOPEN_SOURCE) diff -aurBwbE pwm-20030617/pointer.c pwm-20030617-shape/pointer.c --- pwm-20030617/pointer.c 2003-05-28 23:55:08.000000000 +0200 +++ pwm-20030617-shape/pointer.c 2003-12-08 11:51:45.000000000 +0100 @@ -56,6 +56,19 @@ xret, yret, &wx, &wy, &mask); } +bool is_pointer_on_root() +{ + Window root, win; + int x, y, wx, wy, xret, yret; + uint mask; + + XQueryPointer(wglobal.dpy, SCREEN->root, &root, &win, + &xret, &yret, &wx, &wy, &mask); + if (win == None) + return 1; + + return 0; +} /* */ diff -aurBwbE pwm-20030617/pointer.h pwm-20030617-shape/pointer.h --- pwm-20030617/pointer.h 2003-05-28 23:55:08.000000000 +0200 +++ pwm-20030617-shape/pointer.h 2003-12-08 11:51:45.000000000 +0100 @@ -39,6 +39,7 @@ extern bool handle_button_release(XButtonEvent *ev); extern void handle_pointer_motion(XMotionEvent *ev); extern void get_pointer_rootpos(int *xret, int *yret); +extern bool is_pointer_on_root(); extern void pointer_change_context(WThing *thing, uint actx); extern bool find_window_at(int x, int y, Window *childret); diff -aurBwbE pwm-20030617/thing.c pwm-20030617-shape/thing.c --- pwm-20030617/thing.c 2003-05-28 23:55:08.000000000 +0200 +++ pwm-20030617-shape/thing.c 2003-12-08 11:51:45.000000000 +0100 @@ -28,10 +28,15 @@ void free_thing(WThing *t) { + unsigned int i; + if(wglobal.focus_next==t) wglobal.focus_next=NULL/*(WThing*)SCREEN*/; if(wglobal.grab_holder==t) wglobal.grab_holder=NULL; + for (i = 0; i < SCREEN->n_workspaces; i ++) + if ( wglobal.last_on_workspace[i] == t) + wglobal.last_on_workspace[i] = 0; free(t); } diff -aurBwbE pwm-20030617/workspace.c pwm-20030617-shape/workspace.c --- pwm-20030617/workspace.c 2003-05-28 23:55:08.000000000 +0200 +++ pwm-20030617-shape/workspace.c 2003-12-08 11:51:45.000000000 +0100 @@ -16,6 +16,7 @@ #include "winlist.h" #include "frame.h" #include "focus.h" +#include "pointer.h" bool visible_workspace(int ws) @@ -83,10 +84,18 @@ void do_switch_workspace(int num) { + bool root_after; + dodo_switch_workspace(num); + root_after = is_pointer_on_root(); if(wglobal.current_winobj==NULL || !on_current_workspace(wglobal.current_winobj)){ + if (wglobal.last_on_workspace[num]){ + do_set_focus(wglobal.last_on_workspace[num]); + /* So we don't loose focus on the next workspace */ + wglobal.skip_enter = !root_after; + }else if(circulate(1)==NULL){ do_set_focus((WThing*)SCREEN); wglobal.current_winobj=NULL;