1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-18 20:10:29 +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";
DisableDock = NO;
DisableClip = NO;
DisableDrawers = NO;
Superfluous = YES;
StickyIcons = NO;
SaveSessionOnExit = NO;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

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

View File

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

View File

@@ -433,6 +433,7 @@ typedef struct WPreferences {
struct {
unsigned int nodock:1; /* don't display the dock */
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 noautolaunch:1; /* don't autolaunch apps */
unsigned int norestore:1; /* don't restore session */

View File

@@ -199,7 +199,7 @@ void paint_app_icon(WApplication *wapp)
{
WIcon *icon;
WScreen *scr = wapp->main_window_desc->screen_ptr;
WDock *clip = scr->workspaces[scr->current_workspace]->clip;
WDock *attracting_dock;
int x = 0, y = 0;
Bool update_icon = False;
@@ -213,13 +213,17 @@ void paint_app_icon(WApplication *wapp)
if (wapp->app_icon->docked)
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;
if (!icon->shadowed) {
icon->shadowed = 1;
update_icon = True;
}
wDockAttachIcon(clip, wapp->app_icon, x, y, update_icon);
wDockAttachIcon(attracting_dock, wapp->app_icon, x, y, update_icon);
} else {
/* We must know if the icon is painted in the screen,
* 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)
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);
if (wPreferences.auto_arrange_icons && !wapp->app_icon->attracted)
@@ -270,6 +274,9 @@ void removeAppIconFor(WApplication *wapp)
wAppIconPaint(wapp->app_icon);
} else if (wapp->app_icon->docked) {
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);
} else {
wAppIconDestroy(wapp->app_icon);
@@ -723,9 +730,12 @@ void appIconMouseDown(WObjDescriptor * desc, 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 *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 grabbed = False;
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 */
Bool showed_all_clips = False;
WIcon *icon = aicon->icon;
WScreen *scr = icon->core->screen_ptr;
int clickButton = event->xbutton.button;
Pixmap ghost = None;
Window wins[2]; /* Managing shadow window */
@@ -773,7 +781,7 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
}
else {
ondock = False;
if (wPreferences.flags.nodock && wPreferences.flags.noclip)
if (wPreferences.flags.nodock && wPreferences.flags.noclip && wPreferences.flags.nodrawer)
dockable = 0;
else
dockable = canBeDocked(icon->owner);
@@ -781,21 +789,26 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
/* We try the various docks in that order:
* - First, the dock the appicon comes from, if any
* - Then, the drawers
* - Then, the "dock" (WM_DOCK)
* - Finally, the clip
*/
i = 0;
if (originalDock != NULL)
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)
allDocks[ i++ ] = scr->dock;
if (!wPreferences.flags.noclip &&
originalDock != 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;
wins[0] = icon->core->window;
wins[1] = scr->dock_shadow;
XRestackWindows(dpy, wins, 2);
@@ -856,31 +869,28 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
y = ev.xmotion.y_root - ofs_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;
for (i = 0; dockable && i < 2; i++) {
WDock *theDock = allDocks[i];
if (theDock == NULL)
break;
if (wDockSnapIcon(theDock, aicon, x, y, &ix, &iy, (theDock == originalDock))) {
theNewDock = theDock;
break;
if (!(ev.xmotion.state & MOD_MASK) || aicon->launching || aicon->lock) {
for (i = 0; dockable && i < scr->drawer_count + 2; i++) {
WDock *theDock = allDocks[i];
if (theDock == NULL)
break;
if (wDockSnapIcon(theDock, aicon, x, y, &ix, &iy, (theDock == originalDock))) {
theNewDock = theDock;
break;
}
}
if (originalDock != NULL && theNewDock == NULL &&
(aicon->launching || aicon->lock || aicon->running)) {
/* In those cases, stay in lastDock if no dock really wants us */
theNewDock = lastDock;
}
}
if (originalDock != NULL && theNewDock == NULL &&
(aicon->launching || aicon->lock || aicon->running)) {
/* In those cases, stay in lastDock if no dock really wants us */
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) {
/* Leave lastDock in the state we found it */
if (lastDock->type == WM_DRAWER) {
wDrawerFillTheGap(lastDock, aicon, (lastDock == originalDock));
}
if (collapsed) {
lastDock->collapsed = 1;
wDockHideIcons(lastDock);
@@ -918,6 +928,14 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
lastDock = theNewDock; // i.e., NULL
if (ondock) {
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;
}
@@ -942,6 +960,10 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
command for that appicon, and the user cancels the
wInputDialog asking for one). Make the rejection obvious by
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);
}
}
@@ -956,14 +978,45 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
/* Possible scenario: user moved an auto-attracted appicon
from the clip to the dock, and cancelled the wInputDialog
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);
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
if (lastDock->auto_raise_lower)
wDockLower(lastDock);
// Don't see why I commented out the following 2 lines
/* if (lastDock->auto_raise_lower)
wDockLower(lastDock); */
/* If docked (or tried to dock) to a auto_collapsing dock, unset
* collapsed, so that wHandleAppIconMove doesn't collapse it
* right away (the timer will take care of it) */
@@ -983,13 +1036,23 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
}
}
wDockDetach(originalDock, aicon);
if (originalDock->auto_collapse && !originalDock->collapsed) {
originalDock->collapsed = 1;
wDockHideIcons(originalDock);
}
if (originalDock->auto_raise_lower)
wDockLower(originalDock);
}
}
if (collapsed) {
// Can't remember why the icon hiding is better done above than below (commented out)
// Also, lastDock is quite different from originalDock
/*
if (collapsed) {
lastDock->collapsed = 1;
wDockHideIcons(lastDock);
collapsed = 0;
}
*/
if (superfluous) {
if (ghost != None)
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)
wapp->app_icon = findDockIconFor(scr->dock, main_window);
/* finally check clips */
/* check clips */
if (!wapp->app_icon) {
int 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 (wapp->app_icon) {
WWindow *mainw = wapp->main_window_desc;

View File

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

1429
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_CLIP 1
#define WM_DRAWER 2
int type;
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);
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);
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 wDockTrackWindowLaunch(WDock *dock, Window window);
WAppIcon *wDockFindIconForWindow(WDock *dock, Window window);
@@ -100,14 +104,27 @@ void wClipSaveState(WScreen *scr);
WMPropList *wClipSaveWorkspaceState(WScreen *scr, int workspace);
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);
RImage *wClipMakeTile(WScreen *scr, RImage *normalTile);
RImage* wDrawerMakeTile(WScreen *scr, RImage *normalTile);
#define WO_FAILED 0
#define WO_NOT_APPLICABLE 1
#define WO_SUCCESS 2
typedef enum
{
P_NORMAL = 0,
P_AUTO_RAISE_LOWER,
P_KEEP_ON_TOP,
} dockPosition;
int wClipMakeIconOmnipresent(WAppIcon *aicon, int omnipresent);
#endif

View File

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

View File

@@ -248,11 +248,21 @@ static void icon_update_pixmap(WIcon *icon, RImage *image)
WScreen *scr = icon->core->screen_ptr;
int titled = icon->show_title;
if (icon->tile_type == TILE_NORMAL) {
switch (icon->tile_type) {
case TILE_NORMAL:
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);
tile = RCloneImage(scr->clip_tile);
break;
case TILE_DRAWER:
assert(scr->drawer_tile);
tile = RCloneImage(scr->drawer_tile);
break;
}
if (image) {

View File

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

View File

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

View File

@@ -94,6 +94,7 @@ static WMPropList *dApplications = NULL;
static WMPropList *dWorkspace;
static WMPropList *dDock;
static WMPropList *dClip;
static WMPropList *dDrawers = NULL;
static void make_keys(void)
{
@@ -104,6 +105,7 @@ static void make_keys(void)
dWorkspace = WMCreatePLString("Workspace");
dDock = WMCreatePLString("Dock");
dClip = WMCreatePLString("Clip");
dDrawers = WMCreatePLString("Drawers");
}
/*
@@ -863,6 +865,10 @@ void wScreenRestoreState(WScreen * scr)
state = WMGetFromPLDictionary(scr->session_state, dClip);
scr->clip_icon = wClipRestoreState(scr, state);
}
if (!wPreferences.flags.nodrawer) {
wDrawersRestoreState(scr);
}
wWorkspaceRestoreState(scr);
@@ -910,6 +916,15 @@ void wScreenSaveState(WScreen * scr)
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) {
wSessionSaveState(scr);
} else {

View File

@@ -62,6 +62,12 @@ typedef struct 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
*/
@@ -213,6 +219,7 @@ typedef struct _WScreen {
struct WMenu *workspace_submenu; /* workspace list for window_menu */
struct WDock *dock; /* the application dock */
struct WMenu *dock_pos_menu; /* Dock position menu */
struct WPixmap *dock_dots; /* 3 dots for the Dock */
Window dock_shadow; /* shadow for dock buttons */
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_options; /* Options for Clip */
struct WMenu *clip_ws_menu; /* workspace menu for clip */
struct WMenu *drawer_menu; /* Menu for drawers */
struct WDock *last_dock;
WAppIconChain *global_icons; /* for omnipresent icons chain in clip */
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 */
@@ -233,7 +245,7 @@ typedef struct _WScreen {
struct RImage *icon_tile;
struct RImage *clip_tile;
struct RImage *drawer_tile; /* tile for a drawer (tile + arrow) */
Pixmap icon_tile_pixmap; /* For app supplied icons */
struct RImage *def_icon_rimage; /* Default RImage icon */

View File

@@ -236,16 +236,28 @@ static WMPropList *makeWindowState(WWindow * wwin, WApplication * wapp)
WMReleasePropList(shortcut);
if (wapp && wapp->app_icon && wapp->app_icon->dock) {
int i;
char *name;
char *name = NULL;
if (wapp->app_icon->dock == scr->dock) {
name = "Dock";
} else {
}
if (name == NULL) // Try the clips
{
for (i = 0; i < scr->workspace_count; i++)
if (scr->workspaces[i]->clip == wapp->app_icon->dock)
break;
assert(i < scr->workspace_count);
/*n = i+1; */
name = scr->workspaces[i]->name;
if (i < scr->workspace_count)
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);
WMPutInPLDictionary(win_state, sDock, dock);
@@ -462,7 +474,9 @@ void wSessionRestoreState(WScreen *scr)
if (sscanf(tmp, "%i", &n) != 1) {
if (!strcasecmp(tmp, "DOCK")) {
dock = scr->dock;
} else {
}
if (dock == NULL) // Try the clips
{
for (j = 0; j < scr->workspace_count; j++) {
if (strcmp(scr->workspaces[j]->name, tmp) == 0) {
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 {
if (n == 0) {
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 */

View File

@@ -137,11 +137,40 @@ void DoKaboom(WScreen * scr, Window win, int x, int y)
#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)
{
WScreen *scr = dock->screen_ptr;
WDrawerChain *dc;
WDock *drawer;
XImage *img;
RImage *back, *dock_image;
RImage *back;
Pixmap pixmap;
int i, virtual_tiles, h, j, n;
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)
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++;
h = virtual_tiles * wPreferences.icon_size;
h = (y + h > scr->scr_height) ? scr->scr_height - y : h;
@@ -181,28 +214,24 @@ Pixmap MakeGhostDock(WDock * dock, int sx, int dx, int y)
which = dock->icon_array[i]->icon->pixmap;
else
which = dock->icon_array[i]->icon->core->window;
img = XGetImage(dpy, which, 0, 0, wPreferences.icon_size, n, AllPlanes, ZPixmap);
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);
if (addGhostTile(scr, back, which, j, n, red_mask, green_mask, blue_mask))
return None; /* back is released by addGhostTile */
}
}
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);

View File

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