diff -urN aewm-1.2.4/ChangeLog aewm-1.2.4-virtual-desktops/ChangeLog --- aewm-1.2.4/ChangeLog 2004-10-02 12:34:42.000000000 +0000 +++ aewm-1.2.4-virtual-desktops/ChangeLog 2004-11-07 16:47:09.582804616 +0000 @@ -1,3 +1,9 @@ +1.2.4-virtual-desktops : Frank Hale + + - Added virtual desktops. Use CTRL+ALT+Page Up / CTRL+ALT+Page Down to cycle + added options to set max desktops via aewmrc and/or command line + the default number of virtual desktops is 4. + 1.2.4: - Get rid of type-punned pointers everywhere to appease gcc 3.3. diff -urN aewm-1.2.4/src/aewm.1x aewm-1.2.4-virtual-desktops/src/aewm.1x --- aewm-1.2.4/src/aewm.1x 2004-10-02 12:34:42.000000000 +0000 +++ aewm-1.2.4-virtual-desktops/src/aewm.1x 2004-11-07 16:48:49.038685024 +0000 @@ -75,6 +75,12 @@ .I command when button 3 is clicked on the root window. .TP +.BI --maxdesktops \ number_of_desktops\fP, \ -md \ number_of_desktops +Set +.I maximum +number of virtual desktops. The default is 4. You can switch virtual desktops by +pressing ctrl+alt+page_up or ctl+alt+page_down. +.TP .B \-\-help, \-h Print a short help message to stdout and exit. .TP diff -urN aewm-1.2.4/src/aewm.h aewm-1.2.4-virtual-desktops/src/aewm.h --- aewm-1.2.4/src/aewm.h 2004-10-02 12:34:42.000000000 +0000 +++ aewm-1.2.4-virtual-desktops/src/aewm.h 2004-11-07 16:35:27.835486424 +0000 @@ -21,6 +21,12 @@ #include #endif +/* aewm virtual desktop support */ +#include +#include +#define AEWM_KEY_ALT_COUNT 2 +#define MAX_DESKTOPS 4 + /* Here are the default settings; they can be overriden in aewmrc, * but you can also change them here at compile time. */ @@ -123,6 +129,8 @@ Colormap cmap; int x, y, width, height; int ignore_unmap; + int is_iconified; + int belongs_to_desktop; #ifdef SHAPE Bool has_been_shaped; #endif @@ -141,6 +149,9 @@ extern Display *dpy; extern Window root; extern int screen; +extern int current_desktop; +extern int max_desktops; +extern KeySym AltKeys[]; extern client_t *head_client; extern XFontStruct *font; #ifdef XFT @@ -171,6 +182,7 @@ extern char *opt_new3; extern int opt_bw; extern int opt_pad; +extern int opt_max_desktops; #ifdef SHAPE extern Bool shape; extern int shape_event; @@ -200,8 +212,12 @@ extern void resize(client_t *); extern void hide(client_t *); extern void send_wm_delete(client_t *); +extern void goto_desktop(int); +extern void unhide(client_t *); /* misc.c */ +extern void grabKeys(Window w); +extern void ungrabKeys(Window w); extern void err(const char *, ...); extern void fork_exec(char *); extern void sig_handler(int); diff -urN aewm-1.2.4/src/aewmrc.sample aewm-1.2.4-virtual-desktops/src/aewmrc.sample --- aewm-1.2.4/src/aewmrc.sample 2004-10-02 12:34:42.000000000 +0000 +++ aewm-1.2.4-virtual-desktops/src/aewmrc.sample 2004-11-07 16:18:38.091990768 +0000 @@ -5,6 +5,10 @@ font "lucidasans-10" +# Number of Virtual Desktops +# Use ctrl+alt+page up and page down to switch between them +maxdesktops 4 + # Window colors fgcolor "white" diff -urN aewm-1.2.4/src/events.c aewm-1.2.4-virtual-desktops/src/events.c --- aewm-1.2.4/src/events.c 2004-10-02 13:48:01.000000000 +0000 +++ aewm-1.2.4-virtual-desktops/src/events.c 2004-11-07 16:36:26.573556880 +0000 @@ -2,9 +2,9 @@ * Copyright 1998-2004 Decklin Foster * This program is free software; see LICENSE for details. */ -#include #include "aewm.h" +static void handle_key_press_event(XKeyEvent *); static void handle_button_press(XButtonEvent *); static void handle_button_release(XButtonEvent *); static void handle_configure_request(XConfigureRequestEvent *); @@ -14,6 +14,7 @@ static void handle_client_message(XClientMessageEvent *); static void handle_property_change(XPropertyEvent *); static void handle_enter_event(XCrossingEvent *); +static void handle_leave_event(XCrossingEvent *); static void handle_colormap_change(XColormapEvent *); static void handle_expose_event(XExposeEvent *); #ifdef SHAPE @@ -22,6 +23,8 @@ static int root_button_pressed = 0; +KeySym AltKeys[]={XK_Page_Up,XK_Page_Down}; + /* We may want to put in some sort of check for unknown events at some * point. TWM has an interesting and different way of doing this... */ @@ -35,6 +38,8 @@ show_event(ev); #endif switch (ev.type) { + case KeyPress: + handle_key_press_event(&ev.xkey); break; case ButtonPress: handle_button_press(&ev.xbutton); break; case ButtonRelease: @@ -55,6 +60,8 @@ handle_property_change(&ev.xproperty); break; case EnterNotify: handle_enter_event(&ev.xcrossing); break; + case LeaveNotify: + handle_leave_event(&ev.xcrossing); break; case Expose: handle_expose_event(&ev.xexpose); break; #ifdef SHAPE @@ -66,6 +73,37 @@ } } +static void handle_key_press_event(XKeyEvent *e) +{ + KeySym ks; + + ks=XKeycodeToKeysym(dpy,e->keycode,0); + if (ks==NoSymbol) return; + + switch(ks) + { + case XK_Page_Up: + { + if( current_desktop < max_desktops - 1 ) + { + current_desktop++; + goto_desktop(current_desktop); + } + } + break; + + case XK_Page_Down: + { + if( current_desktop > 0 ) + { + current_desktop--; + goto_desktop(current_desktop); + } + } + break; + } +} + /* Someone clicked a button. If they clicked on a window, we want the * button press, but if they clicked on the root, we're only * interested in the button release. Thus, two functions. @@ -187,6 +225,7 @@ XMapWindow(dpy, c->window); XMapRaised(dpy, c->frame); set_wm_state(c, NormalState); + c->is_iconified=0; } } @@ -280,6 +319,16 @@ if (!c) return; XSetInputFocus(dpy, c->window, RevertToPointerRoot, CurrentTime); XInstallColormap(dpy, c->cmap); + grabKeys(c->window); +} + +static void handle_leave_event(XCrossingEvent *e) +{ + client_t *c = find_client(e->window, MATCH_FRAME); + + if (!c) return; + + ungrabKeys(c->window); } /* Here's part 2 of our colormap policy: when a client installs a new diff -urN aewm-1.2.4/src/init.c aewm-1.2.4-virtual-desktops/src/init.c --- aewm-1.2.4/src/init.c 2004-10-02 12:34:42.000000000 +0000 +++ aewm-1.2.4-virtual-desktops/src/init.c 2004-11-07 16:28:14.667337992 +0000 @@ -10,6 +10,9 @@ Display *dpy; Window root; int screen; +int current_desktop; +int max_desktops; +int opt_max_desktops; XFontStruct *font; #ifdef XFT XftFont *xftfont; @@ -53,6 +56,21 @@ static void read_config_helper(FILE *); static void read_config(char *); +void grabKeys(Window w) +{ + int i; + for(i=0;i]\n" \ " [--font|-fn ]\n" \ @@ -115,7 +133,12 @@ opt_new3 = argv[++i]; continue; } - if ARG("version", "v",0) { + if ARG("maxdesktops", "md", 1) + { + opt_max_desktops = atoi(argv[++i]); + continue; + } + if ARG("version", "v",0) { printf("aewm: version " VERSION "\n"); exit(0); } @@ -161,6 +184,7 @@ XColor dummyc; XGCValues gv; XSetWindowAttributes sattr; + int i; #ifdef SHAPE int dummy; #endif @@ -173,6 +197,15 @@ exit(1); } + if(opt_max_desktops>0) + max_desktops = opt_max_desktops; + else + max_desktops = 4; + + printf("max_desktops = %d\n", max_desktops); + + current_desktop=0; + XSetErrorHandler(handle_xerror); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); @@ -226,8 +259,10 @@ gv.subwindow_mode = IncludeInferiors; invert_gc = XCreateGC(dpy, root, GCFunction|GCSubwindowMode|GCLineWidth|GCFont, &gv); - sattr.event_mask = ChildMask|ColormapChangeMask|ButtonMask; + sattr.event_mask = ChildMask|ColormapChangeMask|ButtonMask|KeyPressMask; XChangeWindowAttributes(dpy, root, CWEventMask, &sattr); + + grabKeys(root); } static void read_config_helper(FILE *rc) @@ -267,8 +302,11 @@ } else if (strcmp(token, "button3") == 0) { if (get_token(&p, token)) opt_new3 = strdup(token); + } else if (strcmp(token, "maxdesktops") == 0) { + if (get_token(&p, token)) + opt_max_desktops = atoi(strdup(token)); } - } + } } } diff -urN aewm-1.2.4/src/manage.c aewm-1.2.4-virtual-desktops/src/manage.c --- aewm-1.2.4/src/manage.c 2004-10-02 12:34:42.000000000 +0000 +++ aewm-1.2.4-virtual-desktops/src/manage.c 2004-11-07 16:37:55.654014592 +0000 @@ -10,6 +10,37 @@ static void draw_outline(client_t *); static int get_incsize(client_t *, int *, int *, int); +void goto_desktop(int d) +{ + unsigned int nwins, i; + Window dummyw1, dummyw2, *wins; + client_t* c; + + if( (d < max_desktops) && (d >= 0) ) + { + current_desktop = d; + + /* Preserve stacking order */ + XQueryTree(dpy, root, &dummyw1, &dummyw2, &wins, &nwins); + for (i = 0; i < nwins; i++) + { + c = find_client(wins[i], MATCH_FRAME); + + if(c) + { + if(c->belongs_to_desktop == current_desktop) + { + if(c->is_iconified==1) unhide(c); + } + else { + if(c->is_iconified==0) hide(c); + } + } + } + XFree(wins); + } +} + void move(client_t *c) { drag(c); @@ -27,12 +58,21 @@ send_config(c); } +void unhide(client_t *c) +{ + XMapWindow(dpy, c->frame); + XMapWindow(dpy, c->window); + set_wm_state(c, NormalState); + c->is_iconified=0; +} + void hide(client_t *c) { if (!c->ignore_unmap) c->ignore_unmap++; XUnmapWindow(dpy, c->frame); XUnmapWindow(dpy, c->window); set_wm_state(c, IconicState); + c->is_iconified=1; } /* The name of this function is a bit misleading: if the client diff -urN aewm-1.2.4/src/misc.c aewm-1.2.4-virtual-desktops/src/misc.c --- aewm-1.2.4/src/misc.c 2004-10-02 12:34:42.000000000 +0000 +++ aewm-1.2.4-virtual-desktops/src/misc.c 2004-11-07 16:31:02.743786488 +0000 @@ -235,6 +235,8 @@ Window dummyw1, dummyw2, *wins; client_t *c; + ungrabKeys(root); + XQueryTree(dpy, root, &dummyw1, &dummyw2, &wins, &nwins); for (i = 0; i < nwins; i++) { c = find_client(wins[i], MATCH_FRAME); diff -urN aewm-1.2.4/src/new.c aewm-1.2.4-virtual-desktops/src/new.c --- aewm-1.2.4/src/new.c 2004-10-02 12:34:42.000000000 +0000 +++ aewm-1.2.4-virtual-desktops/src/new.c 2004-11-07 16:32:33.439998568 +0000 @@ -42,6 +42,8 @@ c->window = w; c->ignore_unmap = 0; + c->belongs_to_desktop = current_desktop; + c->is_iconified=0; c->x = attr.x; c->y = attr.y; c->width = attr.width; @@ -82,6 +84,7 @@ } else { init_position(c); set_wm_state(c, NormalState); + c->is_iconified=0; if ((hints = XGetWMHints(dpy, w))) { if (hints->flags & StateHint) set_wm_state(c, hints->initial_state); XFree(hints); @@ -106,15 +109,18 @@ if (get_wm_state(c) == IconicState) { c->ignore_unmap++; XUnmapWindow(dpy, c->window); + c->is_iconified=1; } else { XMapWindow(dpy, c->window); XMapRaised(dpy, c->frame); set_wm_state(c, NormalState); + c->is_iconified=0; } } else { if (get_wm_state(c) == NormalState) { XMapWindow(dpy, c->window); XMapRaised(dpy, c->frame); + c->is_iconified=0; } }