1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-19 04:20:27 +01:00

Add drawers to wmaker!

Drawers are horizontal docks, and they can themselves only live in the dock

To use them, right click on the dock or a docked appicon and select "Add
a drawer". Then move appicons into the drawer (drag them with the
mouse). You may change the icon of the drawer. By default, drawers
auto-expand and -collapse, and auto-raise/lower. This can be customized
in the same way as for the clip.

Set DisableDrawers to YES in G/D/WindowMaker if you do not want to see
the menu entry to add a drawer.

Just discovered this bug: the auto-attract icon functionality will not
work (to be precise, it crashes WM!) if the clip is disabled
(NoClip=YES). Will fix shortly, of course.
This commit is contained in:
Daniel Déchelotte
2013-04-12 01:42:41 +02:00
committed by Carlos R. Mafra
parent 707ce34a5e
commit e14e6b3da8
19 changed files with 1560 additions and 220 deletions

View File

@@ -43,6 +43,7 @@
NewStyle = "new"; NewStyle = "new";
DisableDock = NO; DisableDock = NO;
DisableClip = NO; DisableClip = NO;
DisableDrawers = NO;
Superfluous = YES; Superfluous = YES;
StickyIcons = NO; StickyIcons = NO;
SaveSessionOnExit = NO; SaveSessionOnExit = NO;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -13,6 +13,7 @@ defsdata_DATA = \
defaultterm.xpm\ defaultterm.xpm\
draw.tiff\ draw.tiff\
draw.xpm\ draw.xpm\
Drawer.png\
Ear.png\ Ear.png\
Ftp.png\ Ftp.png\
GNUstep3D.tiff\ GNUstep3D.tiff\

View File

@@ -3,6 +3,7 @@
Logo.WMPanel = {Icon = GNUstep.tiff;}; Logo.WMPanel = {Icon = GNUstep.tiff;};
Tile.WMClip = {Icon = clip.tiff;}; Tile.WMClip = {Icon = clip.tiff;};
WPrefs = {Icon = "/usr/share/lib/GNUstep/System/Applications/WPrefs.app/WPrefs.tiff";}; WPrefs = {Icon = "/usr/share/lib/GNUstep/System/Applications/WPrefs.app/WPrefs.tiff";};
WMDrawer = { Icon = Drawer.png; };
Dockit = {Icon = GNUstep.tiff;}; Dockit = {Icon = GNUstep.tiff;};
WMSoundServer = {Icon = Sound.tiff;}; WMSoundServer = {Icon = Sound.tiff;};
"*" = {Icon = defaultAppIcon.tiff;}; "*" = {Icon = defaultAppIcon.tiff;};

View File

@@ -433,6 +433,7 @@ typedef struct WPreferences {
struct { struct {
unsigned int nodock:1; /* don't display the dock */ unsigned int nodock:1; /* don't display the dock */
unsigned int noclip:1; /* don't display the clip */ unsigned int noclip:1; /* don't display the clip */
unsigned int nodrawer:1; /* don't use drawers */
unsigned int noupdates:1; /* don't require ~/GNUstep (-static) */ unsigned int noupdates:1; /* don't require ~/GNUstep (-static) */
unsigned int noautolaunch:1; /* don't autolaunch apps */ unsigned int noautolaunch:1; /* don't autolaunch apps */
unsigned int norestore:1; /* don't restore session */ unsigned int norestore:1; /* don't restore session */

View File

@@ -199,7 +199,7 @@ void paint_app_icon(WApplication *wapp)
{ {
WIcon *icon; WIcon *icon;
WScreen *scr = wapp->main_window_desc->screen_ptr; WScreen *scr = wapp->main_window_desc->screen_ptr;
WDock *clip = scr->workspaces[scr->current_workspace]->clip; WDock *attracting_dock;
int x = 0, y = 0; int x = 0, y = 0;
Bool update_icon = False; Bool update_icon = False;
@@ -213,13 +213,17 @@ void paint_app_icon(WApplication *wapp)
if (wapp->app_icon->docked) if (wapp->app_icon->docked)
return; return;
if (clip && clip->attract_icons && wDockFindFreeSlot(clip, &x, &y)) { attracting_dock = scr->attracting_drawer != NULL ?
scr->attracting_drawer :
scr->workspaces[scr->current_workspace]->clip;
if (attracting_dock && attracting_dock->attract_icons &&
wDockFindFreeSlot(attracting_dock, &x, &y)) {
wapp->app_icon->attracted = 1; wapp->app_icon->attracted = 1;
if (!icon->shadowed) { if (!icon->shadowed) {
icon->shadowed = 1; icon->shadowed = 1;
update_icon = True; update_icon = True;
} }
wDockAttachIcon(clip, wapp->app_icon, x, y, update_icon); wDockAttachIcon(attracting_dock, wapp->app_icon, x, y, update_icon);
} else { } else {
/* We must know if the icon is painted in the screen, /* We must know if the icon is painted in the screen,
* because if painted, then PlaceIcon will return the next * because if painted, then PlaceIcon will return the next
@@ -238,7 +242,7 @@ void paint_app_icon(WApplication *wapp)
wapp->app_icon->next == NULL && wapp->app_icon->prev == NULL) wapp->app_icon->next == NULL && wapp->app_icon->prev == NULL)
add_to_appicon_list(scr, wapp->app_icon); add_to_appicon_list(scr, wapp->app_icon);
if (!clip || !wapp->app_icon->attracted || !clip->collapsed) if (!attracting_dock || !wapp->app_icon->attracted || !attracting_dock->collapsed)
XMapWindow(dpy, icon->core->window); XMapWindow(dpy, icon->core->window);
if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted) if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted)
@@ -270,6 +274,9 @@ void removeAppIconFor(WApplication *wapp)
wAppIconPaint(wapp->app_icon); wAppIconPaint(wapp->app_icon);
} else if (wapp->app_icon->docked) { } else if (wapp->app_icon->docked) {
wapp->app_icon->running = 0; wapp->app_icon->running = 0;
if (wapp->app_icon->dock->type == WM_DRAWER) {
wDrawerFillTheGap(wapp->app_icon->dock, wapp->app_icon, True);
}
wDockDetach(wapp->app_icon->dock, wapp->app_icon); wDockDetach(wapp->app_icon->dock, wapp->app_icon);
} else { } else {
wAppIconDestroy(wapp->app_icon); wAppIconDestroy(wapp->app_icon);
@@ -723,9 +730,12 @@ void appIconMouseDown(WObjDescriptor * desc, XEvent * event)
Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event) Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
{ {
WIcon *icon = aicon->icon;
WScreen *scr = icon->core->screen_ptr;
WDock *originalDock = aicon->dock; /* can be NULL */ WDock *originalDock = aicon->dock; /* can be NULL */
WDock *lastDock = originalDock; WDock *lastDock = originalDock;
WDock *allDocks[2]; /* clip and dock (order to be determined at runtime) */ WDock *allDocks[scr->drawer_count + 2]; /* clip, dock and drawers (order determined at runtime) */
WDrawerChain *dc;
Bool done = False, dockable, ondock; Bool done = False, dockable, ondock;
Bool grabbed = False; Bool grabbed = False;
Bool collapsed = False; /* Stores the collapsed state of lastDock, before the moving appicon entered it */ Bool collapsed = False; /* Stores the collapsed state of lastDock, before the moving appicon entered it */
@@ -733,8 +743,6 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
int omnipresent = aicon->omnipresent; /* this must be cached */ int omnipresent = aicon->omnipresent; /* this must be cached */
Bool showed_all_clips = False; Bool showed_all_clips = False;
WIcon *icon = aicon->icon;
WScreen *scr = icon->core->screen_ptr;
int clickButton = event->xbutton.button; int clickButton = event->xbutton.button;
Pixmap ghost = None; Pixmap ghost = None;
Window wins[2]; /* Managing shadow window */ Window wins[2]; /* Managing shadow window */
@@ -773,7 +781,7 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
} }
else { else {
ondock = False; ondock = False;
if (wPreferences.flags.nodock && wPreferences.flags.noclip) if (wPreferences.flags.nodock && wPreferences.flags.noclip && wPreferences.flags.nodrawer)
dockable = 0; dockable = 0;
else else
dockable = canBeDocked(icon->owner); dockable = canBeDocked(icon->owner);
@@ -781,21 +789,26 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
/* We try the various docks in that order: /* We try the various docks in that order:
* - First, the dock the appicon comes from, if any * - First, the dock the appicon comes from, if any
* - Then, the drawers
* - Then, the "dock" (WM_DOCK) * - Then, the "dock" (WM_DOCK)
* - Finally, the clip * - Finally, the clip
*/ */
i = 0; i = 0;
if (originalDock != NULL) if (originalDock != NULL)
allDocks[ i++ ] = originalDock; allDocks[ i++ ] = originalDock;
/* Testing scr->drawers is enough, no need to test wPreferences.flags.nodrawer */
for (dc = scr->drawers; dc != NULL; dc = dc->next) {
if (dc->adrawer != originalDock)
allDocks[ i++ ] = dc->adrawer;
}
if (!wPreferences.flags.nodock && scr->dock != originalDock) if (!wPreferences.flags.nodock && scr->dock != originalDock)
allDocks[ i++ ] = scr->dock; allDocks[ i++ ] = scr->dock;
if (!wPreferences.flags.noclip && if (!wPreferences.flags.noclip &&
originalDock != scr->workspaces[scr->current_workspace]->clip) originalDock != scr->workspaces[scr->current_workspace]->clip)
allDocks[ i++ ] = scr->workspaces[scr->current_workspace]->clip; allDocks[ i++ ] = scr->workspaces[scr->current_workspace]->clip;
for ( ; i < 2; i++) /* In case the clip, the dock, or both, are disabled */ for ( ; i < scr->drawer_count + 2; i++) /* In case the clip, the dock, or both, are disabled */
allDocks[ i ] = NULL; allDocks[ i ] = NULL;
wins[0] = icon->core->window; wins[0] = icon->core->window;
wins[1] = scr->dock_shadow; wins[1] = scr->dock_shadow;
XRestackWindows(dpy, wins, 2); XRestackWindows(dpy, wins, 2);
@@ -856,13 +869,9 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
y = ev.xmotion.y_root - ofs_y; y = ev.xmotion.y_root - ofs_y;
wAppIconMove(aicon, x, y); wAppIconMove(aicon, x, y);
/* At a high level, this if-block is about setting theNewDock to
* the first dock that could snap the appicon at the current
* position, and the next if-block uses that and other info to
* determine whether to dock/undock.
*/
WDock *theNewDock = NULL; WDock *theNewDock = NULL;
for (i = 0; dockable && i < 2; i++) { if (!(ev.xmotion.state & MOD_MASK) || aicon->launching || aicon->lock) {
for (i = 0; dockable && i < scr->drawer_count + 2; i++) {
WDock *theDock = allDocks[i]; WDock *theDock = allDocks[i];
if (theDock == NULL) if (theDock == NULL)
break; break;
@@ -876,11 +885,12 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
/* In those cases, stay in lastDock if no dock really wants us */ /* In those cases, stay in lastDock if no dock really wants us */
theNewDock = lastDock; theNewDock = lastDock;
} }
if (theNewDock != NULL && !aicon->launching && !aicon->lock && ev.xmotion.state & MOD_MASK) }
/* Mod is pressed: do not dock */
theNewDock = NULL;
if (lastDock != NULL && lastDock != theNewDock) { if (lastDock != NULL && lastDock != theNewDock) {
/* Leave lastDock in the state we found it */ /* Leave lastDock in the state we found it */
if (lastDock->type == WM_DRAWER) {
wDrawerFillTheGap(lastDock, aicon, (lastDock == originalDock));
}
if (collapsed) { if (collapsed) {
lastDock->collapsed = 1; lastDock->collapsed = 1;
wDockHideIcons(lastDock); wDockHideIcons(lastDock);
@@ -918,6 +928,14 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
lastDock = theNewDock; // i.e., NULL lastDock = theNewDock; // i.e., NULL
if (ondock) { if (ondock) {
XUnmapWindow(dpy, scr->dock_shadow); XUnmapWindow(dpy, scr->dock_shadow);
/*
* Leaving that weird comment for now.
* But if we see no gap, there is no need to fill one!
* We could test ondock first and the lastDock to NULL afterwards
if (lastDock_before_it_was_null->type == WM_DRAWER) {
wDrawerFillTheGap(lastDock, aicon, (lastDock == originalDock));
} */
} }
ondock = 0; ondock = 0;
} }
@@ -942,6 +960,10 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
command for that appicon, and the user cancels the command for that appicon, and the user cancels the
wInputDialog asking for one). Make the rejection obvious by wInputDialog asking for one). Make the rejection obvious by
sliding the icon to its old position */ sliding the icon to its old position */
if (lastDock->type == WM_DRAWER) {
// Also fill the gap left in the drawer
wDrawerFillTheGap(lastDock, aicon, False);
}
SlideWindow(icon->core->window, x, y, oldX, oldY); SlideWindow(icon->core->window, x, y, oldX, oldY);
} }
} }
@@ -956,14 +978,45 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
/* Possible scenario: user moved an auto-attracted appicon /* Possible scenario: user moved an auto-attracted appicon
from the clip to the dock, and cancelled the wInputDialog from the clip to the dock, and cancelled the wInputDialog
asking for a command */ asking for a command */
if (lastDock->type == WM_DRAWER) {
wDrawerFillTheGap(lastDock, aicon, False);
}
/* If aicon comes from a drawer, make some room to reattach it */
if (originalDock->type == WM_DRAWER) {
WAppIcon *aiconsToShift[ originalDock->icon_count ];
int j = 0;
for (i = 0; i < originalDock->max_icons; i++) {
WAppIcon *ai = originalDock->icon_array[ i ];
if (ai && ai != aicon &&
abs(ai->xindex) >= abs(aicon->xindex))
aiconsToShift[j++] = ai;
}
if (j != originalDock->icon_count - abs(aicon->xindex) - 1)
// Trust this never happens?
wwarning("Shifting j=%d appicons (instead of %d!) to reinsert aicon at index %d.",
j, originalDock->icon_count - abs(aicon->xindex) - 1, aicon->xindex);
wSlideAppicons(aiconsToShift, j, originalDock->on_right_side);
// Trust the appicon is inserted at exactly the same place, so its oldX/oldY are consistent with its "new" location?
}
SlideWindow(icon->core->window, x, y, oldX, oldY); SlideWindow(icon->core->window, x, y, oldX, oldY);
wDockReattachIcon(originalDock, aicon, aicon->xindex, aicon->yindex); wDockReattachIcon(originalDock, aicon, aicon->xindex, aicon->yindex);
} }
else {
if (originalDock->auto_collapse && !originalDock->collapsed) {
originalDock->collapsed = 1;
wDockHideIcons(originalDock);
}
if (originalDock->auto_raise_lower)
wDockLower(originalDock);
}
} }
} }
// No matter what happened above, check to lower lastDock // No matter what happened above, check to lower lastDock
if (lastDock->auto_raise_lower) // Don't see why I commented out the following 2 lines
wDockLower(lastDock); /* if (lastDock->auto_raise_lower)
wDockLower(lastDock); */
/* If docked (or tried to dock) to a auto_collapsing dock, unset /* If docked (or tried to dock) to a auto_collapsing dock, unset
* collapsed, so that wHandleAppIconMove doesn't collapse it * collapsed, so that wHandleAppIconMove doesn't collapse it
* right away (the timer will take care of it) */ * right away (the timer will take care of it) */
@@ -983,13 +1036,23 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
} }
} }
wDockDetach(originalDock, aicon); wDockDetach(originalDock, aicon);
if (originalDock->auto_collapse && !originalDock->collapsed) {
originalDock->collapsed = 1;
wDockHideIcons(originalDock);
}
if (originalDock->auto_raise_lower)
wDockLower(originalDock);
} }
} }
// Can't remember why the icon hiding is better done above than below (commented out)
// Also, lastDock is quite different from originalDock
/*
if (collapsed) { if (collapsed) {
lastDock->collapsed = 1; lastDock->collapsed = 1;
wDockHideIcons(lastDock); wDockHideIcons(lastDock);
collapsed = 0; collapsed = 0;
} }
*/
if (superfluous) { if (superfluous) {
if (ghost != None) if (ghost != None)
XFreePixmap(dpy, ghost); XFreePixmap(dpy, ghost);
@@ -1076,7 +1139,7 @@ static void create_appicon_from_dock(WWindow *wwin, WApplication *wapp, Window m
if (!wapp->app_icon && scr->dock) if (!wapp->app_icon && scr->dock)
wapp->app_icon = findDockIconFor(scr->dock, main_window); wapp->app_icon = findDockIconFor(scr->dock, main_window);
/* finally check clips */ /* check clips */
if (!wapp->app_icon) { if (!wapp->app_icon) {
int i; int i;
for (i = 0; i < scr->workspace_count; i++) { for (i = 0; i < scr->workspace_count; i++) {
@@ -1088,6 +1151,16 @@ static void create_appicon_from_dock(WWindow *wwin, WApplication *wapp, Window m
} }
} }
/* Finally check drawers */
if (!wapp->app_icon) {
WDrawerChain *dc;
for (dc = scr->drawers; dc != NULL; dc = dc->next) {
wapp->app_icon = findDockIconFor(dc->adrawer, main_window);
if (wapp->app_icon)
break;
}
}
/* If created, then set some flags */ /* If created, then set some flags */
if (wapp->app_icon) { if (wapp->app_icon) {
WWindow *mainw = wapp->main_window_desc; WWindow *mainw = wapp->main_window_desc;

View File

@@ -325,6 +325,8 @@ WDefaultEntry staticOptionList[] = {
NULL, getBool, setIfDockPresent, NULL, NULL}, NULL, getBool, setIfDockPresent, NULL, NULL},
{"DisableClip", "NO", (void *)WM_CLIP, {"DisableClip", "NO", (void *)WM_CLIP,
NULL, getBool, setIfDockPresent, NULL, NULL}, NULL, getBool, setIfDockPresent, NULL, NULL},
{"DisableDrawers", "NO", (void *)WM_DRAWER,
NULL, getBool, setIfDockPresent, NULL, NULL},
{"DisableMiniwindows", "NO", NULL, {"DisableMiniwindows", "NO", NULL,
&wPreferences.disable_miniwindows, getBool, NULL, NULL, NULL} &wPreferences.disable_miniwindows, getBool, NULL, NULL, NULL}
}; };
@@ -1132,6 +1134,7 @@ void wReadDefaults(WScreen * scr, WMPropList * new_dict)
void wDefaultUpdateIcons(WScreen *scr) void wDefaultUpdateIcons(WScreen *scr)
{ {
WAppIcon *aicon = scr->app_icon_list; WAppIcon *aicon = scr->app_icon_list;
WDrawerChain *dc;
WWindow *wwin = scr->focused_window; WWindow *wwin = scr->focused_window;
while (aicon) { while (aicon) {
@@ -1144,6 +1147,9 @@ void wDefaultUpdateIcons(WScreen *scr)
if (!wPreferences.flags.noclip) if (!wPreferences.flags.noclip)
wClipIconPaint(scr->clip_icon); wClipIconPaint(scr->clip_icon);
for (dc = scr->drawers; dc != NULL; dc = dc->next)
wDrawerIconPaint(dc->adrawer->icon_array[0]);
while (wwin) { while (wwin) {
if (wwin->icon && wwin->flags.miniaturized) if (wwin->icon && wwin->flags.miniaturized)
wIconChangeImageFile(wwin->icon, NULL); wIconChangeImageFile(wwin->icon, NULL);
@@ -2325,10 +2331,15 @@ static int setIfDockPresent(WScreen * scr, WDefaultEntry * entry, char *flag, lo
switch (which) { switch (which) {
case WM_DOCK: case WM_DOCK:
wPreferences.flags.nodock = wPreferences.flags.nodock || *flag; wPreferences.flags.nodock = wPreferences.flags.nodock || *flag;
// Drawers require the dock
wPreferences.flags.nodrawer = wPreferences.flags.nodrawer || wPreferences.flags.nodock;
break; break;
case WM_CLIP: case WM_CLIP:
wPreferences.flags.noclip = wPreferences.flags.noclip || *flag; wPreferences.flags.noclip = wPreferences.flags.noclip || *flag;
break; break;
case WM_DRAWER:
wPreferences.flags.nodrawer = wPreferences.flags.nodrawer || *flag;
break;
default: default:
break; break;
} }
@@ -2379,6 +2390,13 @@ static int setIconTile(WScreen * scr, WDefaultEntry * entry, WTexture ** texture
scr->clip_tile = wClipMakeTile(scr, img); scr->clip_tile = wClipMakeTile(scr, img);
} }
if (!wPreferences.flags.nodrawer) {
if (scr->drawer_tile) {
RReleaseImage(scr->drawer_tile);
}
scr->drawer_tile = wDrawerMakeTile(scr, img);
}
scr->icon_tile_pixmap = pixmap; scr->icon_tile_pixmap = pixmap;
if (scr->def_icon_rimage) { if (scr->def_icon_rimage) {

1319
src/dock.c

File diff suppressed because it is too large Load Diff

View File

@@ -39,6 +39,7 @@ typedef struct WDock {
#define WM_DOCK 0 #define WM_DOCK 0
#define WM_CLIP 1 #define WM_CLIP 1
#define WM_DRAWER 2
int type; int type;
WMagicNumber auto_expand_magic; WMagicNumber auto_expand_magic;
@@ -66,7 +67,7 @@ typedef struct WDock {
WDock *wDockCreate(WScreen *scr, int type); WDock *wDockCreate(WScreen *scr, int type, char *name);
WDock *wDockRestoreState(WScreen *scr, WMPropList *dock_state, int type); WDock *wDockRestoreState(WScreen *scr, WMPropList *dock_state, int type);
void wDockDestroy(WDock *dock); void wDockDestroy(WDock *dock);
@@ -85,6 +86,9 @@ void wDockDetach(WDock *dock, WAppIcon *icon);
Bool wDockMoveIconBetweenDocks(WDock *src, WDock *dest, WAppIcon *icon, int x, int y); Bool wDockMoveIconBetweenDocks(WDock *src, WDock *dest, WAppIcon *icon, int x, int y);
void wDockReattachIcon(WDock *dock, WAppIcon *icon, int x, int y); void wDockReattachIcon(WDock *dock, WAppIcon *icon, int x, int y);
void wSlideAppicons(WAppIcon **appicons, int n, int to_the_left);
void wDrawerFillTheGap(WDock *drawer, WAppIcon *aicon, Bool redocking);
void wDockFinishLaunch(WDock *dock, WAppIcon *icon); void wDockFinishLaunch(WDock *dock, WAppIcon *icon);
void wDockTrackWindowLaunch(WDock *dock, Window window); void wDockTrackWindowLaunch(WDock *dock, Window window);
WAppIcon *wDockFindIconForWindow(WDock *dock, Window window); WAppIcon *wDockFindIconForWindow(WDock *dock, Window window);
@@ -100,14 +104,27 @@ void wClipSaveState(WScreen *scr);
WMPropList *wClipSaveWorkspaceState(WScreen *scr, int workspace); WMPropList *wClipSaveWorkspaceState(WScreen *scr, int workspace);
WAppIcon *wClipRestoreState(WScreen *scr, WMPropList *clip_state); WAppIcon *wClipRestoreState(WScreen *scr, WMPropList *clip_state);
void wDrawerIconPaint(WAppIcon *dicon);
void wDrawersSaveState(WScreen *scr);
void wDrawersRestoreState(WScreen *scr);
int wIsADrawer(WScreen *scr, WAppIcon *aicon);
void wClipUpdateForWorkspaceChange(WScreen *scr, int workspace); void wClipUpdateForWorkspaceChange(WScreen *scr, int workspace);
RImage *wClipMakeTile(WScreen *scr, RImage *normalTile); RImage *wClipMakeTile(WScreen *scr, RImage *normalTile);
RImage* wDrawerMakeTile(WScreen *scr, RImage *normalTile);
#define WO_FAILED 0 #define WO_FAILED 0
#define WO_NOT_APPLICABLE 1 #define WO_NOT_APPLICABLE 1
#define WO_SUCCESS 2 #define WO_SUCCESS 2
typedef enum
{
P_NORMAL = 0,
P_AUTO_RAISE_LOWER,
P_KEEP_ON_TOP,
} dockPosition;
int wClipMakeIconOmnipresent(WAppIcon *aicon, int omnipresent); int wClipMakeIconOmnipresent(WAppIcon *aicon, int omnipresent);
#endif #endif

View File

@@ -177,8 +177,11 @@ static void panelBtnCallback(WMWidget * self, void *data)
} else { } else {
WAppIcon *aicon = panel->editedIcon; WAppIcon *aicon = panel->editedIcon;
// Cf dock.c:dockIconPaint(WAppIcon *aicon)?
if (aicon == aicon->icon->core->screen_ptr->clip_icon) if (aicon == aicon->icon->core->screen_ptr->clip_icon)
wClipIconPaint(aicon); wClipIconPaint(aicon);
else if (wIsADrawer(aicon->icon->core->screen_ptr, aicon))
wDrawerIconPaint(aicon);
else else
wAppIconPaint(aicon); wAppIconPaint(aicon);

View File

@@ -248,11 +248,21 @@ static void icon_update_pixmap(WIcon *icon, RImage *image)
WScreen *scr = icon->core->screen_ptr; WScreen *scr = icon->core->screen_ptr;
int titled = icon->show_title; int titled = icon->show_title;
if (icon->tile_type == TILE_NORMAL) { switch (icon->tile_type) {
case TILE_NORMAL:
tile = RCloneImage(scr->icon_tile); tile = RCloneImage(scr->icon_tile);
} else { break;
default:
wwarning("Unknown tileType: %d.\n", icon->tile_type);
// fallthrough to TILE_CLIP (emulate previous behaviour)
case TILE_CLIP:
assert(scr->clip_tile); assert(scr->clip_tile);
tile = RCloneImage(scr->clip_tile); tile = RCloneImage(scr->clip_tile);
break;
case TILE_DRAWER:
assert(scr->drawer_tile);
tile = RCloneImage(scr->drawer_tile);
break;
} }
if (image) { if (image) {

View File

@@ -28,6 +28,7 @@
#define TILE_NORMAL 0 #define TILE_NORMAL 0
#define TILE_CLIP 1 #define TILE_CLIP 1
#define TILE_DRAWER 2
typedef struct WIcon { typedef struct WIcon {
WCoreWindow *core; WCoreWindow *core;

View File

@@ -686,8 +686,11 @@ static int real_main(int argc, char **argv)
wPreferences.flags.norestore = 1; wPreferences.flags.norestore = 1;
} else if (strcmp(argv[i], "-nodock") == 0 || strcmp(argv[i], "--no-dock") == 0) { } else if (strcmp(argv[i], "-nodock") == 0 || strcmp(argv[i], "--no-dock") == 0) {
wPreferences.flags.nodock = 1; wPreferences.flags.nodock = 1;
wPreferences.flags.nodrawer = 1;
} else if (strcmp(argv[i], "-noclip") == 0 || strcmp(argv[i], "--no-clip") == 0) { } else if (strcmp(argv[i], "-noclip") == 0 || strcmp(argv[i], "--no-clip") == 0) {
wPreferences.flags.noclip = 1; wPreferences.flags.noclip = 1;
} else if (strcmp(argv[i], "-nodrawer") == 0 || strcmp(argv[i], "--no-drawer") == 0) {
wPreferences.flags.nodrawer = 1;
} else if (strcmp(argv[i], "-version") == 0 || strcmp(argv[i], "--version") == 0) { } else if (strcmp(argv[i], "-version") == 0 || strcmp(argv[i], "--version") == 0) {
printf("Window Maker %s\n", VERSION); printf("Window Maker %s\n", VERSION);
exit(0); exit(0);

View File

@@ -94,6 +94,7 @@ static WMPropList *dApplications = NULL;
static WMPropList *dWorkspace; static WMPropList *dWorkspace;
static WMPropList *dDock; static WMPropList *dDock;
static WMPropList *dClip; static WMPropList *dClip;
static WMPropList *dDrawers = NULL;
static void make_keys(void) static void make_keys(void)
{ {
@@ -104,6 +105,7 @@ static void make_keys(void)
dWorkspace = WMCreatePLString("Workspace"); dWorkspace = WMCreatePLString("Workspace");
dDock = WMCreatePLString("Dock"); dDock = WMCreatePLString("Dock");
dClip = WMCreatePLString("Clip"); dClip = WMCreatePLString("Clip");
dDrawers = WMCreatePLString("Drawers");
} }
/* /*
@@ -864,6 +866,10 @@ void wScreenRestoreState(WScreen * scr)
scr->clip_icon = wClipRestoreState(scr, state); scr->clip_icon = wClipRestoreState(scr, state);
} }
if (!wPreferences.flags.nodrawer) {
wDrawersRestoreState(scr);
}
wWorkspaceRestoreState(scr); wWorkspaceRestoreState(scr);
wScreenUpdateUsableArea(scr); wScreenUpdateUsableArea(scr);
@@ -910,6 +916,15 @@ void wScreenSaveState(WScreen * scr)
wWorkspaceSaveState(scr, old_state); wWorkspaceSaveState(scr, old_state);
if (!wPreferences.flags.nodrawer) {
wDrawersSaveState(scr);
} else {
if ((foo = WMGetFromPLDictionary(old_state, dDrawers)) != NULL) {
WMPutInPLDictionary(scr->session_state, dDrawers, foo);
}
}
if (wPreferences.save_session_on_exit) { if (wPreferences.save_session_on_exit) {
wSessionSaveState(scr); wSessionSaveState(scr);
} else { } else {

View File

@@ -62,6 +62,12 @@ typedef struct WAppIconChain {
} WAppIconChain; } WAppIconChain;
/* Drawers, which are docks, really */
typedef struct WDrawerChain {
struct WDock *adrawer;
struct WDrawerChain *next;
} WDrawerChain;
/* /*
* each WScreen is saved into a context associated with it's root window * each WScreen is saved into a context associated with it's root window
*/ */
@@ -213,6 +219,7 @@ typedef struct _WScreen {
struct WMenu *workspace_submenu; /* workspace list for window_menu */ struct WMenu *workspace_submenu; /* workspace list for window_menu */
struct WDock *dock; /* the application dock */ struct WDock *dock; /* the application dock */
struct WMenu *dock_pos_menu; /* Dock position menu */
struct WPixmap *dock_dots; /* 3 dots for the Dock */ struct WPixmap *dock_dots; /* 3 dots for the Dock */
Window dock_shadow; /* shadow for dock buttons */ Window dock_shadow; /* shadow for dock buttons */
struct WAppIcon *clip_icon; /* The clip main icon */ struct WAppIcon *clip_icon; /* The clip main icon */
@@ -220,9 +227,14 @@ typedef struct _WScreen {
struct WMenu *clip_submenu; /* Workspace list for clips */ struct WMenu *clip_submenu; /* Workspace list for clips */
struct WMenu *clip_options; /* Options for Clip */ struct WMenu *clip_options; /* Options for Clip */
struct WMenu *clip_ws_menu; /* workspace menu for clip */ struct WMenu *clip_ws_menu; /* workspace menu for clip */
struct WMenu *drawer_menu; /* Menu for drawers */
struct WDock *last_dock; struct WDock *last_dock;
WAppIconChain *global_icons; /* for omnipresent icons chain in clip */ WAppIconChain *global_icons; /* for omnipresent icons chain in clip */
int global_icon_count; /* How many global icons do we have */ int global_icon_count; /* How many global icons do we have */
WDrawerChain *drawers; /* Chain of drawers */
/* Cache the following two informations, as they are used quite a lot */
int drawer_count; /* Nb of drawers that */
struct WDock *attracting_drawer; /* The drawer that auto-attracts icons, or NULL */
Window clip_balloon; /* window for workspace name */ Window clip_balloon; /* window for workspace name */
@@ -233,7 +245,7 @@ typedef struct _WScreen {
struct RImage *icon_tile; struct RImage *icon_tile;
struct RImage *clip_tile; struct RImage *clip_tile;
struct RImage *drawer_tile; /* tile for a drawer (tile + arrow) */
Pixmap icon_tile_pixmap; /* For app supplied icons */ Pixmap icon_tile_pixmap; /* For app supplied icons */
struct RImage *def_icon_rimage; /* Default RImage icon */ struct RImage *def_icon_rimage; /* Default RImage icon */

View File

@@ -236,17 +236,29 @@ static WMPropList *makeWindowState(WWindow * wwin, WApplication * wapp)
WMReleasePropList(shortcut); WMReleasePropList(shortcut);
if (wapp && wapp->app_icon && wapp->app_icon->dock) { if (wapp && wapp->app_icon && wapp->app_icon->dock) {
int i; int i;
char *name; char *name = NULL;
if (wapp->app_icon->dock == scr->dock) { if (wapp->app_icon->dock == scr->dock) {
name = "Dock"; name = "Dock";
} else { }
if (name == NULL) // Try the clips
{
for (i = 0; i < scr->workspace_count; i++) for (i = 0; i < scr->workspace_count; i++)
if (scr->workspaces[i]->clip == wapp->app_icon->dock) if (scr->workspaces[i]->clip == wapp->app_icon->dock)
break; break;
assert(i < scr->workspace_count); if (i < scr->workspace_count)
/*n = i+1; */
name = scr->workspaces[i]->name; name = scr->workspaces[i]->name;
} }
if (name == NULL) // Try the drawers
{
WDrawerChain *dc;
for (dc = scr->drawers; dc != NULL; dc = dc->next)
{
if (dc->adrawer == wapp->app_icon->dock)
break;
}
assert(dc != NULL);
name = dc->adrawer->icon_array[0]->wm_instance;
}
dock = WMCreatePLString(name); dock = WMCreatePLString(name);
WMPutInPLDictionary(win_state, sDock, dock); WMPutInPLDictionary(win_state, sDock, dock);
WMReleasePropList(dock); WMReleasePropList(dock);
@@ -462,7 +474,9 @@ void wSessionRestoreState(WScreen *scr)
if (sscanf(tmp, "%i", &n) != 1) { if (sscanf(tmp, "%i", &n) != 1) {
if (!strcasecmp(tmp, "DOCK")) { if (!strcasecmp(tmp, "DOCK")) {
dock = scr->dock; dock = scr->dock;
} else { }
if (dock == NULL) // Try the clips
{
for (j = 0; j < scr->workspace_count; j++) { for (j = 0; j < scr->workspace_count; j++) {
if (strcmp(scr->workspaces[j]->name, tmp) == 0) { if (strcmp(scr->workspaces[j]->name, tmp) == 0) {
dock = scr->workspaces[j]->clip; dock = scr->workspaces[j]->clip;
@@ -470,6 +484,18 @@ void wSessionRestoreState(WScreen *scr)
} }
} }
} }
if (dock == NULL) // Try the drawers
{
WDrawerChain *dc;
for (dc = scr->drawers; dc != NULL; dc = dc->next)
{
if (strcmp(dc->adrawer->icon_array[0]->wm_instance, tmp) == 0)
{
dock = dc->adrawer;
break;
}
}
}
} else { } else {
if (n == 0) { if (n == 0) {
dock = scr->dock; dock = scr->dock;

View File

@@ -772,6 +772,14 @@ void StartUp(Bool defaultScreenOnly)
} }
} }
} }
/* auto-launch apps in drawers */
if (!wPreferences.flags.nodrawer) {
WDrawerChain *dc;
for (dc = wScreen[j]->drawers; dc; dc = dc->next) {
wScreen[j]->last_dock = dc->adrawer;
wDockDoAutoLaunch(dc->adrawer, 0);
}
}
} }
/* go to workspace where we were before restart */ /* go to workspace where we were before restart */

View File

@@ -137,11 +137,40 @@ void DoKaboom(WScreen * scr, Window win, int x, int y)
#endif /* NORMAL_ICON_KABOOM */ #endif /* NORMAL_ICON_KABOOM */
} }
static int addGhostTile(WScreen *scr, RImage *back, Pixmap which, int dy, int height,
unsigned long red_mask, unsigned long green_mask, unsigned long blue_mask)
{
XImage *img;
RImage *dock_image;
img = XGetImage(dpy, which, 0, 0, wPreferences.icon_size, height, AllPlanes, ZPixmap);
if (!img) {
RReleaseImage(back);
return -1;
}
img->red_mask = red_mask;
img->green_mask = green_mask;
img->blue_mask = blue_mask;
dock_image = RCreateImageFromXImage(scr->rcontext, img, NULL);
XDestroyImage(img);
if (!dock_image) {
RReleaseImage(back);
return -1;
}
RCombineAreaWithOpaqueness(back, dock_image, 0, 0, wPreferences.icon_size,
height, 0, dy, 30 * 256 / 100);
RReleaseImage(dock_image);
return 0;
}
Pixmap MakeGhostDock(WDock * dock, int sx, int dx, int y) Pixmap MakeGhostDock(WDock * dock, int sx, int dx, int y)
{ {
WScreen *scr = dock->screen_ptr; WScreen *scr = dock->screen_ptr;
WDrawerChain *dc;
WDock *drawer;
XImage *img; XImage *img;
RImage *back, *dock_image; RImage *back;
Pixmap pixmap; Pixmap pixmap;
int i, virtual_tiles, h, j, n; int i, virtual_tiles, h, j, n;
unsigned long red_mask, green_mask, blue_mask; unsigned long red_mask, green_mask, blue_mask;
@@ -151,6 +180,10 @@ Pixmap MakeGhostDock(WDock * dock, int sx, int dx, int y)
if (dock->icon_array[i] != NULL && dock->icon_array[i]->yindex > virtual_tiles) if (dock->icon_array[i] != NULL && dock->icon_array[i]->yindex > virtual_tiles)
virtual_tiles = dock->icon_array[i]->yindex; virtual_tiles = dock->icon_array[i]->yindex;
} }
for (dc = scr->drawers; dc != NULL; dc = dc->next) {
if (dc->adrawer->y_pos - dock->y_pos > virtual_tiles * wPreferences.icon_size)
virtual_tiles = (dc->adrawer->y_pos - dock->y_pos) / wPreferences.icon_size;
}
virtual_tiles++; virtual_tiles++;
h = virtual_tiles * wPreferences.icon_size; h = virtual_tiles * wPreferences.icon_size;
h = (y + h > scr->scr_height) ? scr->scr_height - y : h; h = (y + h > scr->scr_height) ? scr->scr_height - y : h;
@@ -181,27 +214,23 @@ Pixmap MakeGhostDock(WDock * dock, int sx, int dx, int y)
which = dock->icon_array[i]->icon->pixmap; which = dock->icon_array[i]->icon->pixmap;
else else
which = dock->icon_array[i]->icon->core->window; which = dock->icon_array[i]->icon->core->window;
if (addGhostTile(scr, back, which, j, n, red_mask, green_mask, blue_mask))
img = XGetImage(dpy, which, 0, 0, wPreferences.icon_size, n, AllPlanes, ZPixmap); return None; /* back is released by addGhostTile */
if (!img) {
RReleaseImage(back);
return None;
} }
img->red_mask = red_mask;
img->green_mask = green_mask;
img->blue_mask = blue_mask;
dock_image = RCreateImageFromXImage(scr->rcontext, img, NULL);
XDestroyImage(img);
if (!dock_image) {
RReleaseImage(back);
return None;
}
RCombineAreaWithOpaqueness(back, dock_image, 0, 0,
wPreferences.icon_size, n, 0, j, 30 * 256 / 100);
RReleaseImage(dock_image);
} }
for (dc = scr->drawers; dc != NULL; dc = dc->next) {
Pixmap which;
drawer = dc->adrawer;
if (drawer->y_pos >= scr->scr_height)
continue;
j = drawer->y_pos - dock->y_pos;
n = (h - j < wPreferences.icon_size) ? h - j : wPreferences.icon_size;
if (drawer->icon_array[0]->icon->pixmap)
which = drawer->icon_array[0]->icon->pixmap;
else
which = drawer->icon_array[0]->icon->core->window;
if (addGhostTile(scr, back, which, j, n, red_mask, green_mask, blue_mask))
return None; /* back is released by addGhostTile */
} }
RConvertImage(scr->rcontext, back, &pixmap); RConvertImage(scr->rcontext, back, &pixmap);

View File

@@ -96,7 +96,7 @@ int wWorkspaceNew(WScreen *scr)
} }
if (!wPreferences.flags.noclip) if (!wPreferences.flags.noclip)
wspace->clip = wDockCreate(scr, WM_CLIP); wspace->clip = wDockCreate(scr, WM_CLIP, NULL);
list = wmalloc(sizeof(WWorkspace *) * scr->workspace_count); list = wmalloc(sizeof(WWorkspace *) * scr->workspace_count);