diff -Nur WindowMaker-0.90.0/WPrefs.app/Workspace.c WindowMaker-0.90.0-vertical/WPrefs.app/Workspace.c --- WindowMaker-0.90.0/WPrefs.app/Workspace.c 2004-10-12 22:19:43.000000000 +0200 +++ WindowMaker-0.90.0-vertical/WPrefs.app/Workspace.c 2004-10-26 10:38:08.410478944 +0200 @@ -49,6 +49,7 @@ WMPopUpButton *posP; WMFrame *dockF; + WMButton *dockAlignment[2]; WMButton *dockB; WMButton *clipB; } _Panel; @@ -127,6 +128,15 @@ WMSetButtonSelected(panel->newB, GetBoolForKey("AdvanceToNewWorkspace")); + str = GetStringForKey("DockAlignment"); + if (!str) + str = "h"; + if(!strncmp(str,"h",1)) { + WMSetButtonSelected(panel->dockAlignment[0], 1); + } else { + WMSetButtonSelected(panel->dockAlignment[1], 1); + } + WMSetButtonSelected(panel->dockB, !GetBoolForKey("DisableDock")); WMSetButtonSelected(panel->clipB, !GetBoolForKey("DisableClip")); @@ -283,6 +293,17 @@ WMMoveWidget(panel->dockF, 390, 10); WMSetFrameTitle(panel->dockF, _("Dock/Clip")); + panel->dockAlignment[0] = WMCreateRadioButton(panel->dockF); + WMResizeWidget(panel->dockAlignment[0], 30, 20); + WMMoveWidget(panel->dockAlignment[0], 25, 13); + WMSetButtonText(panel->dockAlignment[0], _("h")); + + panel->dockAlignment[1] = WMCreateRadioButton(panel->dockF); + WMGroupButtons(panel->dockAlignment[0], panel->dockAlignment[1]); + WMResizeWidget(panel->dockAlignment[1], 30, 18); + WMMoveWidget(panel->dockAlignment[1], 60, 13); + WMSetButtonText(panel->dockAlignment[1], _("v")); + panel->dockB = WMCreateButton(panel->dockF, WBTToggle); WMResizeWidget(panel->dockB, 64, 64); WMMoveWidget(panel->dockB, 25, 35); @@ -344,6 +365,12 @@ SetBoolForKey(WMGetButtonSelected(panel->cyclB), "CycleWorkspaces"); SetBoolForKey(WMGetButtonSelected(panel->newB), "AdvanceToNewWorkspace"); + if(WMGetButtonSelected(panel->dockAlignment[1])) { + SetStringForKey("v", "DockAlignment"); + } else { + SetStringForKey("h", "DockAlignment"); + } + SetBoolForKey(!WMGetButtonSelected(panel->dockB), "DisableDock"); SetBoolForKey(!WMGetButtonSelected(panel->clipB), "DisableClip"); diff -Nur WindowMaker-0.90.0/src/WindowMaker.h WindowMaker-0.90.0-vertical/src/WindowMaker.h --- WindowMaker-0.90.0/src/WindowMaker.h 2004-10-18 02:17:06.000000000 +0200 +++ WindowMaker-0.90.0-vertical/src/WindowMaker.h 2004-10-25 12:56:34.000000000 +0200 @@ -373,6 +373,7 @@ char modelock; #endif + char dock_alignment; /* dock alignment v or h*/ char no_dithering; /* use dithering or not */ char no_sound; /* enable/disable sound */ diff -Nur WindowMaker-0.90.0/src/defaults.c WindowMaker-0.90.0-vertical/src/defaults.c --- WindowMaker-0.90.0/src/defaults.c 2004-10-23 01:58:59.000000000 +0200 +++ WindowMaker-0.90.0-vertical/src/defaults.c 2004-10-25 12:56:34.000000000 +0200 @@ -120,6 +120,7 @@ static int getPathList(); static int getEnum(); static int getTexture(); +static int getDockAlignment(); static int getWSBackground(); static int getWSSpecificBackground(); static int getFont(); @@ -139,6 +140,7 @@ /* static int setPositive(); */ +static int setDockAlignment(); static int setWidgetColor(); static int setIconTile(); static int setWinTitleFont(); @@ -380,6 +382,9 @@ WDefaultEntry optionList[] = { /* dynamic options */ + {"DockAlignment", "h", NULL, + &wPreferences.dock_alignment, getDockAlignment, setDockAlignment + }, {"IconPosition", "blh", seIconPositions, &wPreferences.icon_yard, getEnum, setIconPosition }, @@ -1542,8 +1547,21 @@ return -1; } +static int +getDockAlignment(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr, + void **ret) +{ + static char data; + char *val; - + GET_STRING_OR_DEFAULT("DockAlignment", val); + if (ret) + *ret = val; + if (addr) { + *(char*)addr = *val; + } + return True; +} /* * value - is the value in the defaults DB @@ -3319,6 +3337,115 @@ return 0; } +static int +setDockAlignment(WScreen *scr, WDefaultEntry *entry, WMPropList *value, + void *bar) +{ + int x=0,y=0,i; + int dock_width; + int dock_height; + if(scr->dock) { + for (i=0; idock->max_icons; i++) { + if(scr->dock->icon_array[i]!=NULL) { + if(scr->dock->icon_array[i]->xindex > x) {x = scr->dock->icon_array[i]->xindex;} + if(scr->dock->icon_array[i]->yindex > y) {y = scr->dock->icon_array[i]->yindex;} + } + } + x++; y++; + dock_width=x*wPreferences.icon_size; + dock_height=y*wPreferences.icon_size; + { + int tmp=scr->dock->x_pos; + scr->dock->x_pos=scr->dock->y_pos; + scr->dock->y_pos=tmp; + tmp=dock_width; + dock_width=dock_height; + dock_height=tmp; + } + if(scr->dock->align=='h') { + scr->dock->align='v'; + } else { + scr->dock->align='h'; + if(dock_height>scr->scr_height-DOCK_EXTRA_SPACE) { + dock_height=scr->scr_height-DOCK_EXTRA_SPACE; + } + } + if(scr->dock->align=='h') { + if (scr->dock->y_pos <= DOCK_EXTRA_SPACE) + scr->dock->y_pos = DOCK_EXTRA_SPACE; + else if (scr->dock->y_pos > scr->scr_height - dock_height - DOCK_EXTRA_SPACE) { + scr->dock->y_pos = scr->scr_height - dock_height - DOCK_EXTRA_SPACE; + } + if (scr->dock->x_pos<=DOCK_EXTRA_SPACE) { + scr->dock->x_pos=DOCK_EXTRA_SPACE; + scr->dock->on_right_side = 0; + } else { + scr->dock->x_pos=scr->scr_width-DOCK_EXTRA_SPACE-wPreferences.icon_size;; + scr->dock->on_right_side = 1; + } + } else { /* vertical alignment */ + if (scr->dock->y_pos <= DOCK_EXTRA_SPACE) { + scr->dock->y_pos = DOCK_EXTRA_SPACE; + scr->dock->on_top = 1; + } else { + scr->dock->y_pos = scr->scr_height - DOCK_EXTRA_SPACE - wPreferences.icon_size; + scr->dock->on_top = 0; + } + if (scr->dock->x_pos>scr->scr_width-dock_width-DOCK_EXTRA_SPACE) { + scr->dock->x_pos=scr->scr_width-dock_width-DOCK_EXTRA_SPACE; + } else if(scr->dock->x_pos<=DOCK_EXTRA_SPACE) { + scr->dock->x_pos=DOCK_EXTRA_SPACE; + } + } + for (i=0; idock->icon_count; i++) { + WAppIcon *aicon = scr->dock->icon_array[i]; + if (aicon) { + { + int tmp = aicon->xindex; + aicon->xindex = aicon->yindex; + aicon->yindex = tmp; + aicon->dock = scr->dock; + } + aicon->x_pos = scr->dock->x_pos + (aicon->xindex*wPreferences.icon_size); + aicon->y_pos = scr->dock->y_pos + (aicon->yindex*wPreferences.icon_size); + + if (scr->dock->lowered) + ChangeStackingLevel(aicon->icon->core, WMNormalLevel); + else + ChangeStackingLevel(aicon->icon->core, WMDockLevel); + + wCoreConfigure(aicon->icon->core, aicon->x_pos, aicon->y_pos, + 0, 0); + + if (!scr->dock->collapsed) + XMapWindow(dpy, aicon->icon->core->window); + wRaiseFrame(aicon->icon->core); + } + } + + /* if the first icon is not defined, use the default */ + { + WAppIcon *old_top = scr->dock->icon_array[0]; + if (scr->dock->icon_array[0]==NULL) { + /* update default icon */ + old_top->x_pos = scr->dock->x_pos; + old_top->y_pos = scr->dock->y_pos; + if (scr->dock->lowered) + ChangeStackingLevel(old_top->icon->core, WMNormalLevel); + else + ChangeStackingLevel(old_top->icon->core, WMDockLevel); + scr->dock->icon_array[0] = old_top; + XMoveWindow(dpy, old_top->icon->core->window, scr->dock->x_pos, scr->dock->y_pos); + } else if (old_top!=scr->dock->icon_array[0]) { + if (old_top == scr->clip_icon) + scr->clip_icon = scr->dock->icon_array[0]; + wAppIconDestroy(old_top); + } + } + } + wScreenUpdateUsableArea(scr); + return 0; +} static int setWorkspaceBack(WScreen *scr, WDefaultEntry *entry, WMPropList *value, diff -Nur WindowMaker-0.90.0/src/dock.c WindowMaker-0.90.0-vertical/src/dock.c --- WindowMaker-0.90.0/src/dock.c 2004-10-23 05:10:40.000000000 +0200 +++ WindowMaker-0.90.0-vertical/src/dock.c 2004-10-26 10:15:54.924199672 +0200 @@ -1193,11 +1193,15 @@ dock = wmalloc(sizeof(WDock)); memset(dock, 0, sizeof(WDock)); + dock->align=wPreferences.dock_alignment; if (type == WM_CLIP) icon_count = CLIP_MAX_ICONS; - else + else if(dock->align=='h') { icon_count = scr->scr_height/wPreferences.icon_size; + } else { + icon_count = scr->scr_width/wPreferences.icon_size; + } dock->icon_array = wmalloc(sizeof(WAppIcon*)*icon_count); memset(dock->icon_array, 0, sizeof(WAppIcon*)*icon_count); @@ -1214,6 +1218,7 @@ dock->type = type; dock->icon_count = 1; dock->on_right_side = 1; + dock->on_top = 1; dock->collapsed = 0; dock->auto_collapse = 0; dock->auto_collapse_magic = NULL; @@ -1440,9 +1445,15 @@ WMPutInPLDictionary(dock_state, key, list); WMReleasePropList(key); + if(dock->align=='h') { + snprintf(buffer, sizeof(buffer), "%i,%i,%c", + (dock->on_right_side ? -ICON_SIZE : 0), + dock->y_pos,dock->align); + } else { + snprintf(buffer, sizeof(buffer), "%i,%i,%c", dock->x_pos, + (dock->on_top ? 0 : -ICON_SIZE),dock->align); + } - snprintf(buffer, sizeof(buffer), "%i,%i", (dock->on_right_side ? -ICON_SIZE : 0), - dock->y_pos); value = WMCreatePLString(buffer); WMPutInPLDictionary(dock_state, dPosition, value); WMReleasePropList(value); @@ -1544,7 +1555,7 @@ static WAppIcon* -restore_icon_state(WScreen *scr, WMPropList *info, int type, int index) +restore_icon_state(WScreen *scr, WMPropList *info, int type, int index, char align) { WAppIcon *aicon; WMPropList *cmd, *value; @@ -1648,10 +1659,23 @@ /* check position sanity */ /* incomplete section! */ if (type == WM_DOCK) { - aicon->xindex = 0; - if (aicon->yindex < 0) - wwarning(_("bad value in docked icon position %i,%i"), - aicon->xindex, aicon->yindex); + if(align=='h') { + if(aicon->xindex > 0) { + aicon->yindex = aicon->xindex; + } + aicon->xindex = 0; + if (aicon->yindex < 0) + wwarning(_("bad value in docked icon position %i,%i"), + aicon->xindex, aicon->yindex); + } else { + if(aicon->yindex > 0) { + aicon->xindex = aicon->yindex; + } + aicon->yindex = 0; + if (aicon->xindex < 0) + wwarning(_("bad value in docked icon position %i,%i"), + aicon->xindex, aicon->yindex); + } } } else { aicon->yindex = index; @@ -1759,20 +1783,15 @@ } else { WMRect rect; int flags; + char old_align; - if (sscanf(WMGetFromPLString(value), "%i,%i", &dock->x_pos, - &dock->y_pos)!=2) + if (sscanf(WMGetFromPLString(value), "%i,%i,%c", &dock->x_pos, + &dock->y_pos,&old_align)!=3) COMPLAIN("Position"); - - /* check position sanity */ - rect.pos.x = dock->x_pos; - rect.pos.y = dock->y_pos; - rect.size.width = rect.size.height = ICON_SIZE; - - wGetRectPlacementInfo(scr, rect, &flags); - if (flags & (XFLAG_DEAD | XFLAG_PARTIAL)) { - int x = dock->x_pos; - wScreenKeepInside(scr, &x, &dock->y_pos, ICON_SIZE, ICON_SIZE); + if(old_align!=dock->align) { + int tmp=dock->x_pos; + dock->x_pos=dock->y_pos; + dock->y_pos=tmp; } /* Is this needed any more? */ @@ -1783,14 +1802,35 @@ dock->x_pos = scr->scr_width-ICON_SIZE; } } else { - if (dock->x_pos >= 0) { - dock->x_pos = DOCK_EXTRA_SPACE; - dock->on_right_side = 0; + if(dock->align=='h') { + if (dock->x_pos >= 0) { + dock->x_pos = DOCK_EXTRA_SPACE; + dock->on_right_side = 0; + } else { + dock->x_pos = scr->scr_width - DOCK_EXTRA_SPACE - ICON_SIZE; + dock->on_right_side = 1; + } } else { - dock->x_pos = scr->scr_width - DOCK_EXTRA_SPACE - ICON_SIZE; - dock->on_right_side = 1; + if (dock->y_pos >= 0) { + dock->y_pos = DOCK_EXTRA_SPACE; + dock->on_top = 1; + } else { + dock->y_pos = scr->scr_height - DOCK_EXTRA_SPACE - ICON_SIZE; + dock->on_top = 0; + } } } + + /* check position sanity */ + rect.pos.x = dock->x_pos; + rect.pos.y = dock->y_pos; + rect.size.width = rect.size.height = ICON_SIZE; + + wGetRectPlacementInfo(scr, rect, &flags); + if (flags & (XFLAG_DEAD | XFLAG_PARTIAL)) { + int x = dock->x_pos; + wScreenKeepInside(scr, &x, &dock->y_pos, ICON_SIZE, ICON_SIZE); + } } } @@ -1925,7 +1965,8 @@ } value = WMGetFromPLArray(apps, i); - aicon = restore_icon_state(scr, value, type, dock->icon_count); + aicon = restore_icon_state(scr, value, type, dock->icon_count, dock->align); + dock->icon_array[dock->icon_count] = aicon; @@ -2496,7 +2537,7 @@ return False; } - if (dock->type == WM_DOCK) { + if (dock->type == WM_DOCK && dock->align=='h') { if (icon->dock != dock && ex_x != 0) return False; @@ -2573,6 +2614,83 @@ return True; } } + } else if (dock->type == WM_DOCK && dock->align=='v') { + if (icon->dock != dock && ex_y != 0) + return False; + + aicon = NULL; + for (i=0; imax_icons; i++) { + nicon = dock->icon_array[i]; + if (nicon && nicon->xindex == ex_x) { + aicon = nicon; + break; + } + } + + if (redocking) { + int sig, done, closest; + + /* Possible cases when redocking: + * + * icon dragged out of range of any slot -> false + * icon dragged to range of free slot + * icon dragged to range of same slot + * icon dragged to range of different icon + */ + if (abs(ex_y) > DOCK_DETTACH_THRESHOLD) + return False; + + if (ex_x>=0 && ex_x<=max_x_icons && (aicon==icon || !aicon)) { + *ret_x = ex_x; + *ret_y = 0; + return True; + } + + /* start looking at the upper slot or lower? */ + if (ex_x*ICON_SIZE < (req_x + offset - dx)) + sig = 1; + else + sig = -1; + + closest = -1; + done = 0; + /* look for closest free slot */ + for (i=0; i<(DOCK_DETTACH_THRESHOLD+1)*2 && !done; i++) { + int j; + + done = 1; + closest = sig*(i/2) + ex_x; + /* check if this slot is used */ + if (closest >= 0) { + for (j = 0; jmax_icons; j++) { + if (dock->icon_array[j] + && dock->icon_array[j]->yindex==closest) { + /* slot is used by someone else */ + if (dock->icon_array[j]!=icon) + done = 0; + break; + } + } + } + sig = -sig; + } + if (done && closest >= 0 && closest <= max_x_icons && + ((ex_x >= closest && ex_x - closest < DOCK_DETTACH_THRESHOLD+1) + || + (ex_x < closest && closest - ex_x <= DOCK_DETTACH_THRESHOLD+1))) { + *ret_x = closest; + *ret_y = 0; + return True; + } + } else { /* !redocking */ + + /* if slot is free and the icon is close enough, return it */ + if (!aicon && ex_y == 0 && ex_x >= 0 && ex_x <= max_x_icons) { + *ret_x = ex_x; + *ret_y = 0; + return True; + } + } } else { /* CLIP */ int neighbours = 0; int start, stop, k; @@ -2935,23 +3053,35 @@ { WScreen *scr = dock->screen_ptr; WAppIcon *btn; - int x, i; + int x,y,i; - - if (dock->on_right_side) { - x = dock->x_pos = scr->scr_width - ICON_SIZE - DOCK_EXTRA_SPACE; + if(dock->align=='h') { + if (dock->on_right_side) { + x = dock->x_pos = scr->scr_width - ICON_SIZE - DOCK_EXTRA_SPACE; + } else { + x = dock->x_pos = DOCK_EXTRA_SPACE; + } + for (i=0; imax_icons; i++) { + btn = dock->icon_array[i]; + if (btn) { + btn->x_pos = x; + XMoveWindow(dpy, btn->icon->core->window, btn->x_pos, btn->y_pos); + } + } } else { - x = dock->x_pos = DOCK_EXTRA_SPACE; - } - - for (i=0; imax_icons; i++) { - btn = dock->icon_array[i]; - if (btn) { - btn->x_pos = x; - XMoveWindow(dpy, btn->icon->core->window, btn->x_pos, btn->y_pos); + if (dock->on_top) { + y = dock->y_pos = DOCK_EXTRA_SPACE; + } else { + y = dock->y_pos = scr->scr_height - ICON_SIZE - DOCK_EXTRA_SPACE; + } + for (i=0; imax_icons; i++) { + btn = dock->icon_array[i]; + if (btn) { + btn->y_pos = y; + XMoveWindow(dpy, btn->icon->core->window, btn->x_pos, btn->y_pos); + } } } - wScreenUpdateUsableArea(scr); } @@ -3393,7 +3523,7 @@ WMenuEntry *entry; WApplication *wapp = NULL; int index = 0; - int x_pos; + int x_pos,y_pos; int n_selected; int appIsRunning = aicon->running && aicon->icon && aicon->icon->owner; @@ -3531,17 +3661,30 @@ if (dock->type == WM_CLIP) { /*x_pos = event->xbutton.x_root+2;*/ x_pos = event->xbutton.x_root - dock->menu->frame->core->width/2 - 1; + y_pos = event->xbutton.y_root- dock->menu->frame->core->height/2 - 1; if (x_pos < 0) { x_pos = 0; } else if (x_pos + dock->menu->frame->core->width > scr->scr_width-2) { x_pos = scr->scr_width - dock->menu->frame->core->width - 4; } + if (y_pos < 0) { + y_pos = 0; + } else if (y_pos + dock->menu->frame->core->height > scr->scr_height-2) { + y_pos = scr->scr_height - dock->menu->frame->core->height - 4; + } } else { - x_pos = dock->on_right_side ? - scr->scr_width - dock->menu->frame->core->width - 3 : 0; + if(dock->align=='h') { + x_pos = dock->on_right_side ? + scr->scr_width - dock->menu->frame->core->width - 3 : 0; + y_pos = event->xbutton.y_root+3; + } else { + x_pos = event->xbutton.x_root+3; + y_pos = dock->on_top ? + event->xbutton.y_root+3 : event->xbutton.y_root - dock->menu->frame->core->height - 3; + } } - wMenuMapAt(dock->menu, x_pos, event->xbutton.y_root+2, False); + wMenuMapAt(dock->menu, x_pos, y_pos, False); /* allow drag select */ event->xany.send_event = True; @@ -3608,11 +3751,13 @@ { WScreen *scr = dock->screen_ptr; int ofs_x=event->xbutton.x, ofs_y=event->xbutton.y; - int x, y; + int x, y, i; XEvent ev; int grabbed = 0, swapped = 0, done; Pixmap ghost = None; int superfluous = wPreferences.superfluous; /* we catch it to avoid problems */ + int docked_entrys_in_x = 0; + int docked_entrys_in_y = 0; #ifdef DEBUG puts("moving dock"); @@ -3622,14 +3767,24 @@ GrabModeAsync, None, None, CurrentTime) !=GrabSuccess) { wwarning("pointer grab failed for dock move"); } - y = 0; - for (x=0; xmax_icons; x++) { - if (dock->icon_array[x]!=NULL && - dock->icon_array[x]->yindex > y) - y = dock->icon_array[x]->yindex; + for (i=0; imax_icons; i++) { + if (dock->icon_array[i]!=NULL) { + if(dock->icon_array[i]->xindex > docked_entrys_in_x) { + docked_entrys_in_x = dock->icon_array[i]->xindex; + } + if(dock->icon_array[i]->yindex > docked_entrys_in_y) { + docked_entrys_in_y = dock->icon_array[i]->yindex; + } + } + } + docked_entrys_in_x++; + docked_entrys_in_y++; + + if(dock->align=='h') { + XResizeWindow(dpy, scr->dock_shadow, ICON_SIZE, ICON_SIZE*docked_entrys_in_y); + } else { + XResizeWindow(dpy, scr->dock_shadow, ICON_SIZE*docked_entrys_in_x, ICON_SIZE); } - y++; - XResizeWindow(dpy, scr->dock_shadow, ICON_SIZE, ICON_SIZE*y); done = 0; while (!done) { @@ -3657,7 +3812,7 @@ wScreenKeepInside(scr, &x, &y, ICON_SIZE, ICON_SIZE); moveDock(dock, x, y); - } else { + } else if(dock->align=='h') { /* move vertically if pointer is inside the dock*/ if ((dock->on_right_side && ev.xmotion.x_root >= dock->x_pos - ICON_SIZE) @@ -3720,6 +3875,65 @@ } } } + } else { + if ((dock->on_top && + ev.xmotion.y_root <= dock->y_pos + ICON_SIZE) + || (!dock->on_top && + ev.xmotion.y_root >= dock->y_pos)) { + + if (ev.xmotion.x_root - ofs_x < 0) { + x = 0; + } else if (ev.xmotion.x_root - ofs_x + ICON_SIZE*docked_entrys_in_x > scr->scr_width) { + x = scr->scr_width - ICON_SIZE*docked_entrys_in_x; + } else { + x = ev.xmotion.x_root - ofs_x; + } + moveDock(dock, x, dock->y_pos); + } + /* move horizontally to change sides */ + x = ev.xmotion.x_root - ofs_x; + if (dock->on_top) { + if (ev.xmotion.y_root > dock->y_pos + ICON_SIZE*2) { + XMoveWindow(dpy, scr->dock_shadow, dock->x_pos, + scr->scr_height-ICON_SIZE-DOCK_EXTRA_SPACE-1); + if (superfluous && ghost==None) { + ghost = MakeGhostDockV(dock, dock->x_pos, + dock->y_pos, + scr->scr_height-ICON_SIZE-DOCK_EXTRA_SPACE-1); + XSetWindowBackgroundPixmap(dpy, scr->dock_shadow,ghost); + XClearWindow(dpy, scr->dock_shadow); + } + XMapRaised(dpy, scr->dock_shadow); + swapped = 1; + } else { + if (superfluous && ghost!=None) { + XFreePixmap(dpy, ghost); + ghost = None; + } + XUnmapWindow(dpy, scr->dock_shadow); + swapped = 0; + } + } else { + if (ev.xmotion.y_root < dock->y_pos - ICON_SIZE) { + XMoveWindow(dpy, scr->dock_shadow,dock->x_pos, + DOCK_EXTRA_SPACE+1); + if (superfluous && ghost==None) { + ghost = MakeGhostDockV(dock, dock->x_pos,dock->y_pos, + 0); + XSetWindowBackgroundPixmap(dpy, scr->dock_shadow, ghost); + XClearWindow(dpy, scr->dock_shadow); + } + XMapRaised(dpy, scr->dock_shadow); + swapped = -1; + } else { + XUnmapWindow(dpy, scr->dock_shadow); + swapped = 0; + if (superfluous && ghost!=None) { + XFreePixmap(dpy, ghost); + ghost = None; + } + } + } } break; @@ -3733,13 +3947,24 @@ XUnmapWindow(dpy, scr->dock_shadow); XResizeWindow(dpy, scr->dock_shadow, ICON_SIZE, ICON_SIZE); if (dock->type == WM_DOCK) { - if (swapped!=0) { - if (swapped>0) - dock->on_right_side = 1; - else - dock->on_right_side = 0; - swapDock(dock); - wArrangeIcons(scr, False); + if(dock->align=='h') { + if (swapped!=0) { + if (swapped>0) + dock->on_right_side = 1; + else + dock->on_right_side = 0; + swapDock(dock); + wArrangeIcons(scr, False); + } + } else { + if (swapped!=0) { + if (swapped>0) + dock->on_top = 0; + else + dock->on_top = 1; + swapDock(dock); + wArrangeIcons(scr, False); + } } } done = 1; diff -Nur WindowMaker-0.90.0/src/dock.h WindowMaker-0.90.0-vertical/src/dock.h --- WindowMaker-0.90.0/src/dock.h 2004-10-14 19:31:49.000000000 +0200 +++ WindowMaker-0.90.0-vertical/src/dock.h 2004-10-25 12:56:34.000000000 +0200 @@ -51,6 +51,9 @@ unsigned int auto_collapse:1; /* if clip auto-collapse itself */ unsigned int auto_raise_lower:1; /* if clip should raise/lower when * entered/leaved */ + char align; + unsigned int on_top:1; + unsigned int on_right_side:1; unsigned int collapsed:1; unsigned int mapped:1; diff -Nur WindowMaker-0.90.0/src/dockedapp.c WindowMaker-0.90.0-vertical/src/dockedapp.c --- WindowMaker-0.90.0/src/dockedapp.c 2004-10-14 19:31:49.000000000 +0200 +++ WindowMaker-0.90.0-vertical/src/dockedapp.c 2004-10-25 12:56:34.778515552 +0200 @@ -454,6 +454,7 @@ */ { WMRect rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); + int dock_head = wGetHeadForRect(scr, rect); y = aicon->y_pos; if (y < 0) @@ -462,12 +463,31 @@ y = rect.pos.y + rect.size.height - PHEIGHT - 30; if (aicon->dock && aicon->dock->type == WM_DOCK) { - if (aicon->dock->on_right_side) - x = rect.pos.x + rect.size.width/2; - else - x = rect.pos.x + rect.size.width/2 - PWIDTH - 2; + if(aicon->dock->align=='h') { + if (aicon->dock->on_right_side) + x = rect.pos.x + rect.size.width/2; + else + x = rect.pos.x + rect.size.width/2 - PWIDTH - 2; + } else { + x = aicon->x_pos; + if(x>scr->scr_width-PWIDTH) { + x=scr->scr_width-PWIDTH; + } + if (aicon->dock->on_top && y==0) { + y = wPreferences.icon_size; + } else if(!aicon->dock->on_top && (y >= scr->scr_height - wPreferences.icon_size - PHEIGHT - 30 - DOCK_EXTRA_SPACE)) { + y = scr->scr_height - PHEIGHT - 30 - wPreferences.icon_size - DOCK_EXTRA_SPACE; + } + } } else { x = rect.pos.x + (rect.size.width - PWIDTH)/2; + if(scr->dock->align!='h') { + if(ydock->on_top) { + y = wPreferences.icon_size; + } else if(y>scr->scr_height-PHEIGHT-30-wPreferences.icon_size-DOCK_EXTRA_SPACE && !scr->dock->on_top) { + y = scr->scr_height-PHEIGHT-30-wPreferences.icon_size-DOCK_EXTRA_SPACE; + } + } } } diff -Nur WindowMaker-0.90.0/src/screen.c WindowMaker-0.90.0-vertical/src/screen.c --- WindowMaker-0.90.0/src/screen.c 2004-10-17 00:16:21.000000000 +0200 +++ WindowMaker-0.90.0-vertical/src/screen.c 2004-10-25 12:56:34.780515248 +0200 @@ -852,10 +852,18 @@ (!scr->dock->lowered || wPreferences.no_window_over_dock)) { int offset = wPreferences.icon_size + DOCK_EXTRA_SPACE; - if (scr->dock->on_right_side) { - scr->totalUsableArea[i].x2 -= offset; + if (scr->dock->align=='h') { + if (scr->dock->on_right_side) { + scr->totalUsableArea[i].x2 -= offset; + } else { + scr->totalUsableArea[i].x1 += offset; + } } else { - scr->totalUsableArea[i].x1 += offset; + if (scr->dock->on_top) { + scr->totalUsableArea[i].y1 += offset; + } else { + scr->totalUsableArea[i].y2 -= offset; + } } } diff -Nur WindowMaker-0.90.0/src/superfluous.c WindowMaker-0.90.0-vertical/src/superfluous.c --- WindowMaker-0.90.0/src/superfluous.c 2004-10-12 19:46:38.000000000 +0200 +++ WindowMaker-0.90.0-vertical/src/superfluous.c 2004-10-25 12:56:34.782514944 +0200 @@ -374,6 +374,86 @@ return pixmap; } +Pixmap +MakeGhostDockV(WDock *dock, int x, int sy, int dy) +{ + WScreen *scr = dock->screen_ptr; + XImage *img; + RImage *back, *dock_image; + Pixmap pixmap; + int i, virtual_tiles, w, j, n; + unsigned long red_mask, green_mask, blue_mask; + + virtual_tiles = 0; + for (i=0; imax_icons; i++) { + if (dock->icon_array[i]!=NULL && + dock->icon_array[i]->xindex > virtual_tiles) + virtual_tiles = dock->icon_array[i]->xindex; + } + virtual_tiles++; + w = virtual_tiles * wPreferences.icon_size; + w = (x + w > scr->scr_width) ? scr->scr_width-x : w; + virtual_tiles = w / wPreferences.icon_size; /* The visible ones */ + if (w % wPreferences.icon_size) + virtual_tiles++; /* There is one partially visible tile at end */ + + img=XGetImage(dpy, scr->root_win, x, dy, w, wPreferences.icon_size, + AllPlanes, ZPixmap); + if (!img) + return None; + + red_mask = img->red_mask; + green_mask = img->green_mask; + blue_mask = img->blue_mask; + + back = RCreateImageFromXImage(scr->rcontext, img, NULL); + XDestroyImage(img); + if (!back) { + return None; + } + + for (i=0;imax_icons;i++) { + if (dock->icon_array[i]!=NULL && + dock->icon_array[i]->xindex < virtual_tiles) { + Pixmap which; + j = dock->icon_array[i]->xindex * wPreferences.icon_size; + n = (w - j < wPreferences.icon_size) ? w - j : + wPreferences.icon_size; + if (dock->icon_array[i]->icon->pixmap) + which = dock->icon_array[i]->icon->pixmap; + else + which = dock->icon_array[i]->icon->core->window; + + img=XGetImage(dpy, which, 0, 0, n, wPreferences.icon_size, + 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, + n,wPreferences.icon_size, + j, 0, 30 * 256 / 100); + RReleaseImage(dock_image); + } + } + + + RConvertImage(scr->rcontext, back, &pixmap); + + RReleaseImage(back); + + return pixmap; +} Pixmap MakeGhostIcon(WScreen *scr, Drawable drawable) diff -Nur WindowMaker-0.90.0/src/superfluous.h WindowMaker-0.90.0-vertical/src/superfluous.h --- WindowMaker-0.90.0/src/superfluous.h 2004-10-12 19:58:51.000000000 +0200 +++ WindowMaker-0.90.0-vertical/src/superfluous.h 2004-10-25 12:56:34.000000000 +0200 @@ -26,4 +26,5 @@ extern void DoKaboom(); extern Pixmap MakeGhostDock(); +extern Pixmap MakeGhostDockV(); extern Pixmap MakeGhostIcon();