We can handle windows while swithing windows (ie alt tabbing) in the
switch pannel.
ex: alt+tab + [ minimize | hide | close | shade ... ]

these operations should be initialized with shortcuts
containing the 'alt' (or equivalent) key of the switching shortcut.

ex:     switch window --> mod1+tab
        close window  --> mod1+k


7 files changed, 164 insertions(+), 25 deletions(-)
WindowMaker/Pixmaps/Makefile.am |    3 +
src/WindowMaker.h               |    1 
src/cycling.c                   |   59 ++++++++++++++++++++++--------
src/defaults.c                  |   36 +++++++++++++++++-
src/event.c                     |   11 ++++-
src/switchpanel.c               |   75 +++++++++++++++++++++++++++++++++++++--
src/switchpanel.h               |    4 ++


# HG changeset patch
# User Samir SAADA <[EMAIL PROTECTED]>
# Date 1227348522 -3600
# Node ID f8ec1b413499918e85ba63843753c94672db6c6a
# Parent  be392fd85635001243fb45fa7d18c294e3f85b5a
Advanced operations on switch panel

We can handle windows while swithing windows (ie alt tabbing) in the
switch pannel.
ex: alt+tab + [ minimize | hide | close | shade ... ]

these operations should be initialized with shortcuts
containing the 'alt' (or equivalent) key of the switching shortcut.

ex: 	switch window --> mod1+tab
	close window  --> mod1+k

diff --git a/WindowMaker/Pixmaps/Makefile.am b/WindowMaker/Pixmaps/Makefile.am
--- a/WindowMaker/Pixmaps/Makefile.am
+++ b/WindowMaker/Pixmaps/Makefile.am
@@ -5,6 +5,7 @@
 		tile.xpm \
 		swtile.png \
 		swback.png \
-		swback2.png
+		swback2.png \
+		swkill.png 
 
 EXTRA_DIST = $(defsdata_DATA)
diff --git a/WindowMaker/Pixmaps/swkill.png b/WindowMaker/Pixmaps/swkill.png
new file mode 100644
index 0000000000000000000000000000000000000000..eb9444dc662edb9de6a2365769e2d6db63b1aa32
GIT binary patch
literal 1431
[EMAIL PROTECTED]($-P)<h;3K|Lk000e1NJLTq002M$002M;[EMAIL PROTECTED]
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
[EMAIL PROTECTED]>>%f6HkmbjVBSGzHaY({o0UPfbHarKP1%
zVPHB!I%+9p7m9)[EMAIL PROTECTED]
zd%k`9_8#}ZIe$1DSbOdNTHk+v-~KLZi>gx1m{xQGMWZG_(FqidngB&7P&[EMAIL PROTECTED]
zs0mPX0!8D3^BPU$YM>2h0h)k$<=+|Lc=<O3^Z;F`9-Z`*CVeR^(h4jC+JVbb-rWoA
z20lXdSiXrFCQks7W?%!bnCwHX1ndH~p*os1wf`f30YvJ7PGBX_kS{r-z+0&[EMAIL PROTECTED]
z0Yv5iF9Fx)N9x3vz;mdc&[EMAIL PROTECTED];ZNA$pvj0lI;2fPP>Y_zjp2TnSuJ{+|yl1SEp%
zM_?<e$1|m!ivS{50o#BXAs$1(JHS_o$FN8Xum-q|@[EMAIL PROTECTED];HG7BIw3)q4C
z$&UeV1G~JttG!Gg0PYO&*bi(#^&cPlY;R|gI&93l8s87BLG`_iV|4_$G~)U~;0a&y
ztkcsv;5vuB8|#{fGO>#^051dA$9Ud_$YQS$-a|m73HT7WFmUBC_T*3b5m)[EMAIL PROTECTED]<
z!aI%uD^M+^36rG<tY>25N3l0^*2dQXFOt0R0L{R?X+!x5AhG~h>bUYMs=s(~p5>kf
zynrp8qu>&`1Cfi;g!AnI%N+Oi0-t;[EMAIL PROTECTED]@0ym`z=_|mE4%_Rf
z{_Dv%-uP#MTVp(XfKBC{qD%1hG-1;VVBP=nfOQ!7HZ|8-P63_<mc)4WVsrlZVrnN4
ze2XtaWO~xjK0Tn#Ve7(oI<dw-i4ChL9KsrZvSLx~1NH{|8h}Mf!}|!Zz+v0%!84A>
zfE6)5M}SULe|KCv=&[EMAIL PROTECTED]>L;GP(-eys6f>wVX(<I2$q9|4*iw&Bz)
zBAc-{c@&NU>tl9&{SKQeM<?>=0Vh*$L_{_M_s4h*Vo!c3#?K|dr1pRy>Qi}(tOM4@
zc>Rh!`N0H?Uc10?_y`c}jx);[EMAIL PROTECTED]>m47{!UZ}66P~Egd-915CH6$I~pRZfK4%8
z!&u{8-8u~CT>#gZY>B)>[EMAIL PROTECTED]&O{E?LT%y-!0-WwJ82+-%SwS;<$+zo7v;XHvY
zat?ds<64&YCB4~4fG&rvt-OCf7b44n$7A?LfsLsCoH`ScnM^!^E&<;qrARM;B^oSQ
zH4{9u6Ilv8MfAz;[EMAIL PROTECTED]([EMAIL PROTECTED])[EMAIL PROTECTED]
zrEEMz8gWmjuG~W5E5Ii}aO>NIoz2~XZEK^r$AE`W{lPOn*g|[EMAIL PROTECTED]>ac1r
zB3}Tv2d;DijYK#8FJKF*2fShfh+KnvCAmFq?J&!sXfyBu>FR%{fz7CP`vnC=F2U*$
z7YD8k0n5`K!TT?Ttz4a^NLd0N&Y|(IF|[EMAIL PROTECTED]>-IZ<
zR>[EMAIL PROTECTED])MN!3$%J+EkHv+4HRk$}^2e1`ns(L_$KBwYnEATGi#nA!a
zec)qMPbB1=jm`5Nz^o9jDNr1(FeNIFm$2irpRnWy%KwUOYUW~V`*y767d1quP<gz<
[EMAIL PROTECTED]@gilgek6|M<[EMAIL PROTECTED]@+
lY629UK+&iPP;>%C<[EMAIL PROTECTED]

diff --git a/src/WindowMaker.h b/src/WindowMaker.h
--- a/src/WindowMaker.h
+++ b/src/WindowMaker.h
@@ -473,6 +473,7 @@
     char workspace_border_position;     /* Where to leave a workspace border */
 
     RImage *swtileImage;
+    RImage *swkillImage;
     RImage *swbackImage[9];
 
     struct {
diff --git a/src/cycling.c b/src/cycling.c
--- a/src/cycling.c
+++ b/src/cycling.c
@@ -71,11 +71,13 @@
     Bool done = False;
     WWindow *newFocused;
     WWindow *oldFocused;
+    WMArray *windowsToClose=WMCreateArray(1);
     int modifiers;
+    Bool closingAction = False;
     XModifierKeymap *keymap = NULL;
     Bool hasModifier;
-    Bool somethingElse = False;
-    XEvent ev;
+    XEvent ev;    
+    XEvent closingEvent;
     WSwitchPanel *swpanel = NULL;
     KeyCode leftKey, rightKey, homeKey, endKey, shiftLKey, shiftRKey;
 
@@ -186,13 +188,32 @@
                         }
                     }
                 }
-            } else if (ev.xkey.keycode != shiftLKey && ev.xkey.keycode != shiftRKey) {
+            } else if (wKeyBindings[WKBD_CLOSE].keycode == ev.xkey.keycode) {
+#ifdef DEBUG
+                printf("Got closing Action\n");
+#endif
+                if (swpanel) {
+                    closingAction = True;
+                    int winIndex = WMFindInArray(windowsToClose, NULL, newFocused);
+                    if (winIndex != WANotFound) {
+                        WMDeleteFromArray(windowsToClose, winIndex);
+                        wSwitchPanelMarkCurrent(swpanel, 0);
+                    } else {
+                        WMAddToArray(windowsToClose, newFocused);		      
+                        closingEvent = ev;//>>>>>>>:( ugly I know 
+                        wSwitchPanelMarkCurrent(swpanel, 1);
+                    }
+                }
+	    } else if (ev.xkey.keycode != shiftLKey && ev.xkey.keycode != shiftRKey) {
 #ifdef DEBUG
                 printf("Got something else\n");
 #endif
-                somethingElse = True;
-                done = True;
-            }
+                if(WMFindInArray(windowsToClose, NULL, newFocused) == WANotFound){
+                    wSetFocusTo(scr, newFocused);
+                    WMHandleEvent(&ev);
+                    wSwitchPanelRefreshImages(swpanel, newFocused);
+                }
+	    }
             break;
         case KeyRelease:
 #ifdef DEBUG
@@ -249,19 +270,27 @@
 
     if (swpanel)
         wSwitchPanelDestroy(swpanel);
-
-    if (newFocused) {
-        wRaiseFrame(newFocused->frame->core);
-        CommitStacking(scr);
-        if (!newFocused->flags.mapped)
-            wMakeWindowVisible(newFocused);
-        wSetFocusTo(scr, newFocused);
+    
+    if (closingAction){
+        WWindow *aWindow;
+        int i;
+        WM_ITERATE_ARRAY(windowsToClose, aWindow , i){
+            wSetFocusTo(scr, aWindow);
+            WMHandleEvent(&closingEvent);
+        }
+        WMEmptyArray(windowsToClose);
     }
+    else
+        if (newFocused) {
+            wRaiseFrame(newFocused->frame->core);
+            CommitStacking(scr);
+            if (!newFocused->flags.mapped)
+                wMakeWindowVisible(newFocused);
+            wSetFocusTo(scr, newFocused);
+        }
 
     scr->flags.doing_alt_tab = 0;
 
-    if (somethingElse)
-        WMHandleEvent(&ev);
 }
 
 
diff --git a/src/defaults.c b/src/defaults.c
--- a/src/defaults.c
+++ b/src/defaults.c
@@ -659,7 +659,7 @@
     {"IconTitleBack",	"black",       		NULL,
     NULL,				getColor,	setIconTitleBack
     },
-    {"SwitchPanelImages", "(swtile.png, swback.png, 30, 40)",  &wPreferences,
+    {"SwitchPanelImages", "(swtile.png, swback.png, 30, 40, swkill.png)",  &wPreferences,
     NULL,               getPropList,     setSwPOptions
     },
     /* keybindings */
@@ -3585,14 +3585,18 @@
     if (!WMIsPLArray(array) || WMGetPropListItemCount(array)==0) {
         if (prefs->swtileImage) RReleaseImage(prefs->swtileImage);
         prefs->swtileImage= NULL;
- 
+        
+        if (prefs->swkillImage) RReleaseImage(prefs->swkillImage);
+        prefs->swkillImage= NULL;
+
+
         WMReleasePropList(array);
         return 0;
     }
 
     switch (WMGetPropListItemCount(array))
     {
-    case 4:
+    case 5:
         if (!WMIsPLString(WMGetFromPLArray(array, 1))) {
             wwarning(_("Invalid arguments for option \"%s\""),
                      entry->key);
@@ -3687,8 +3691,34 @@
                 wwarning(_("Could not load image \"%s\" for option \"%s\""), 
                          path, entry->key);
             }
+            
             wfree(path);
         }
+
+        //-----------------------------------------------------------
+        if (!WMIsPLString(WMGetFromPLArray(array, 4))) {
+            wwarning(_("Invalid arguments for option \"%s\""),
+                     entry->key);
+            break;
+        } else
+          path= FindImage(wPreferences.pixmap_path, WMGetFromPLString(WMGetFromPLArray(array, 4)));
+
+        if (!path) {
+            wwarning(_("Could not find image \"%s\" for option \"%s\""), 
+                     WMGetFromPLString(WMGetFromPLArray(array, 4)),
+                     entry->key);
+        } else {
+            if (prefs->swkillImage) RReleaseImage(prefs->swkillImage);
+
+            prefs->swkillImage= RLoadImage(scr->rcontext, path, 4);
+            if (!prefs->swkillImage) {
+                wwarning(_("Could not load image \"%s\" for option \"%s\""), 
+                         path, entry->key);
+            }
+            
+            wfree(path);
+        }
+        //-------------------------------------------------------------
         break;
 
     default:
diff --git a/src/event.c b/src/event.c
--- a/src/event.c
+++ b/src/event.c
@@ -1359,8 +1359,7 @@
             break;
         }
     }
-
-
+    
     if (command < 0) {
 #ifdef LITE
         {
@@ -1523,7 +1522,13 @@
         break;
     case WKBD_CLOSE:
         if (ISMAPPED(wwin) && ISFOCUSED(wwin) && !WFLAGP(wwin, no_closable)) {
-            CloseWindowMenu(scr);
+            CloseWindowMenu(scr); 
+            if (wwin->protocols.DELETE_WINDOW)
+                wClientSendProtocol(wwin, _XA_WM_DELETE_WINDOW,
+                                    event->xkey.time);
+        }
+        else if(scr->flags.doing_alt_tab){//todo test this if no danger
+            printf("alt_tabing, close \n");
             if (wwin->protocols.DELETE_WINDOW)
                 wClientSendProtocol(wwin, _XA_WM_DELETE_WINDOW,
                                     event->xkey.time);
diff --git a/src/switchpanel.c b/src/switchpanel.c
--- a/src/switchpanel.c
+++ b/src/switchpanel.c
@@ -50,6 +50,7 @@
     WMArray *icons;
     WMArray *images;
     WMArray *windows;
+    WMArray *markedWindows;
     RImage *bg;
     int current;
     int firstVisible;
@@ -61,6 +62,7 @@
     
     RImage *tileTmp;
     RImage *tile;
+    RImage *kill;
     
     WMFont *font;
     WMColor *white;
@@ -75,6 +77,7 @@
 #define BORDER_SPACE 10
 #define ICON_SIZE 48
 #define ICON_TILE_SIZE 64
+#define ICON_KILL_SIZE 64
 #define LABEL_HEIGHT 25
 #define SCREEN_BORDER_SPACING 2*20
 #define SCROLL_STEPS (ICON_TILE_SIZE/2)
@@ -110,11 +113,15 @@
         RImage *back;
         int opaq= 255;
         RImage *tile;
+        RImage *kill;
         WMPoint pos;
+
         Pixmap p;
-
-        if (canReceiveFocus(WMGetFromArray(panel->windows, idecks)) < 0)
+	
+	Window *theWindow = WMGetFromArray(panel->windows, idecks);
+        if (canReceiveFocus(theWindow) < 0){
           opaq= 50;
+	}
 
         pos= WMGetViewPosition(WMWidgetView(icon));
         back= panel->tileTmp;
@@ -138,10 +145,18 @@
             tile= panel->tile;
             RCombineArea(back, tile, 0, 0, tile->width, tile->height,
                          (back->width - tile->width)/2, (back->height - tile->height)/2);
-        }
+        } 
+         
+
         RCombineAreaWithOpaqueness(back, image, 0, 0, image->width, image->height,
                                    (back->width - image->width)/2, (back->height - image->height)/2,
                                    opaq);
+        if (selected == -1 ||
+            WMFindInArray(panel->markedWindows, NULL, theWindow) != WANotFound) {
+            kill= panel->kill;
+            RCombineArea(back, kill, 0, 0, kill->width, kill->height,
+                         (back->width - kill->width)/2, (back->height - kill->height)/2);
+        }
 
         RConvertImage(panel->scr->rcontext, back, &p);
         XSetWindowBackgroundPixmap(dpy, WMWidgetXID(icon), p);
@@ -353,6 +368,20 @@
     return stile;
 }
 
+static RImage *getKill(WSwitchPanel *panel)
+{
+    RImage *sKill;
+
+    if (!wPreferences.swkillImage)
+        return NULL;
+
+    sKill = RScaleImage(wPreferences.swkillImage, ICON_KILL_SIZE, ICON_KILL_SIZE);
+    if (!sKill)
+        return wPreferences.swkillImage;
+    
+    return sKill;
+}
+
 
 static void
 drawTitle(WSwitchPanel *panel, int idecks, char *title)
@@ -452,6 +481,9 @@
 
     panel->windows= makeWindowListArray(scr, curwin, workspace,
                                         wPreferences.swtileImage!=0);
+   
+    panel->markedWindows= WMCreateArray(1);
+    
     count= WMGetArrayItemCount(panel->windows);
     
     if (count == 0) {
@@ -477,6 +509,7 @@
 
     panel->tileTmp= RCreateImage(ICON_TILE_SIZE, ICON_TILE_SIZE, 1);
     panel->tile= getTile(panel);
+    panel->kill= getKill(panel);
     if (panel->tile && wPreferences.swbackImage[8]) {
         panel->bg= createBackImage(scr, width+2*BORDER_SPACE, height+2*BORDER_SPACE);
     }
@@ -490,6 +523,9 @@
         if (panel->tileTmp)
           RReleaseImage(panel->tileTmp);
         panel->tileTmp= NULL;
+        if (panel->kill)
+          RReleaseImage(panel->kill);
+        panel->kill= NULL;
     }
 
     panel->white= WMWhiteColor(scr->wmscreen);
@@ -602,6 +638,8 @@
       RReleaseImage(panel->tile);
     if (panel->tileTmp)
       RReleaseImage(panel->tileTmp);
+    if (panel->kill)
+        RReleaseImage(panel->kill);
     if (panel->bg)
       RReleaseImage(panel->bg);
     if (panel->font)
@@ -609,6 +647,37 @@
     if (panel->white)
       WMReleaseColor(panel->white);
     wfree(panel);
+}
+
+
+void wSwitchPanelRefreshImages(WSwitchPanel *panel, WWindow *focus){
+    WWindow *wwin;
+    int i;
+    //if it is faster to check application than rendering all windows
+    Window *win = (Window*)wApplicationOf(focus->main_window);
+    WM_ITERATE_ARRAY(panel->windows, wwin, i) { 
+        if(win == (Window*)wApplicationOf(wwin->main_window))
+            changeImage(panel, i, 0); 
+    }
+    
+    if (panel->current >= 0)
+        changeImage(panel, panel->current, 1);
+    
+}
+
+
+void wSwitchPanelMarkCurrent(WSwitchPanel *panel, int mark){
+    if (panel->current >= 0){
+        if(mark){
+            WMAddToArray(panel->markedWindows, 
+                         WMGetFromArray(panel->windows, panel->current));
+            changeImage(panel, panel->current, -1);
+        }else{
+            WMRemoveFromArray(panel->markedWindows, 
+                              WMGetFromArray(panel->windows, panel->current));
+            changeImage(panel, panel->current, 1);
+        }
+    }
 }
 
 
diff --git a/src/switchpanel.h b/src/switchpanel.h
--- a/src/switchpanel.h
+++ b/src/switchpanel.h
@@ -35,4 +35,8 @@
 
 Window wSwitchPanelGetWindow(WSwitchPanel *swpanel);
 
+void wSwitchPanelRefreshImages(WSwitchPanel *panel, WWindow *wwin);
+
+void wSwitchPanelMarkCurrent(WSwitchPanel *panel, int mark);
+
 #endif /* _SWITCHPANEL_H_ */

Reply via email to