mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-21 05:18:06 +01:00
Real-time dock left-right swapping
No more ghost dock when switching sides: the real swap happens immediately, you can still adjust vertically afterwards. Removed two functions in superfluous that are no longer used
This commit is contained in:
committed by
Carlos R. Mafra
parent
cf5fdca63d
commit
5e004d5f11
106
src/dock.c
106
src/dock.c
@@ -3622,7 +3622,7 @@ static void handleDockMove(WDock *dock, WAppIcon *aicon, XEvent *event)
|
|||||||
int x = aicon->x_pos, y = aicon->y_pos;;
|
int x = aicon->x_pos, y = aicon->y_pos;;
|
||||||
int shad_x = x, shad_y = y;
|
int shad_x = x, shad_y = y;
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
int grabbed = 0, swapped = 0, done;
|
int grabbed = 0, done, previously_on_right, now_on_right, previous_x_pos;
|
||||||
Pixmap ghost = None;
|
Pixmap ghost = None;
|
||||||
int superfluous = wPreferences.superfluous; /* we catch it to avoid problems */
|
int superfluous = wPreferences.superfluous; /* we catch it to avoid problems */
|
||||||
|
|
||||||
@@ -3648,23 +3648,10 @@ static void handleDockMove(WDock *dock, WAppIcon *aicon, XEvent *event)
|
|||||||
XClearWindow(dpy, scr->dock_shadow);
|
XClearWindow(dpy, scr->dock_shadow);
|
||||||
}
|
}
|
||||||
XMapWindow(dpy, scr->dock_shadow);
|
XMapWindow(dpy, scr->dock_shadow);
|
||||||
} else {
|
|
||||||
int i;
|
|
||||||
WDrawerChain *dc;
|
|
||||||
/* Find out the actual height of the dock, to create its shadow */
|
|
||||||
y = 0;
|
|
||||||
for (i = 0; i < dock->max_icons; i++) {
|
|
||||||
if (dock->icon_array[i] != NULL && dock->icon_array[i]->yindex > y)
|
|
||||||
y = dock->icon_array[i]->yindex;
|
|
||||||
}
|
|
||||||
for (dc = scr->drawers; dc; dc = dc->next) {
|
|
||||||
if ((dc->adrawer->y_pos - dock->y_pos) / ICON_SIZE > y)
|
|
||||||
y = (dc->adrawer->y_pos - dock->y_pos) / ICON_SIZE;
|
|
||||||
}
|
|
||||||
y++;
|
|
||||||
XResizeWindow(dpy, scr->dock_shadow, ICON_SIZE, ICON_SIZE * y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
previously_on_right = now_on_right = dock->on_right_side;
|
||||||
|
previous_x_pos = dock->x_pos;
|
||||||
done = 0;
|
done = 0;
|
||||||
while (!done) {
|
while (!done) {
|
||||||
WMMaskEvent(dpy, PointerMotionMask | ButtonReleaseMask | ButtonPressMask
|
WMMaskEvent(dpy, PointerMotionMask | ButtonReleaseMask | ButtonPressMask
|
||||||
@@ -3700,61 +3687,25 @@ static void handleDockMove(WDock *dock, WAppIcon *aicon, XEvent *event)
|
|||||||
moveDock(dock, x, y);
|
moveDock(dock, x, y);
|
||||||
break;
|
break;
|
||||||
case WM_DOCK:
|
case WM_DOCK:
|
||||||
/* move vertically if pointer is inside the dock */
|
|
||||||
if ((dock->on_right_side && ev.xmotion.x_root >= dock->x_pos - ICON_SIZE)
|
|
||||||
|| (!dock->on_right_side && ev.xmotion.x_root <= dock->x_pos + ICON_SIZE * 2)) {
|
|
||||||
|
|
||||||
x = ev.xmotion.x_root - ofs_x;
|
|
||||||
y = ev.xmotion.y_root - ofs_y;
|
|
||||||
wScreenKeepInside(scr, &x, &y, ICON_SIZE, ICON_SIZE);
|
|
||||||
moveDock(dock, dock->x_pos, y);
|
|
||||||
}
|
|
||||||
/* move horizontally to change sides */
|
|
||||||
x = ev.xmotion.x_root - ofs_x;
|
x = ev.xmotion.x_root - ofs_x;
|
||||||
if (!dock->on_right_side) {
|
y = ev.xmotion.y_root - ofs_y;
|
||||||
|
if (previously_on_right)
|
||||||
/* is on left */
|
{
|
||||||
if (ev.xmotion.x_root > dock->x_pos + ICON_SIZE * 2) {
|
now_on_right = (ev.xmotion.x_root >= previous_x_pos - ICON_SIZE);
|
||||||
XMoveWindow(dpy, scr->dock_shadow, scr->scr_width - ICON_SIZE
|
|
||||||
- DOCK_EXTRA_SPACE - 1, dock->y_pos);
|
|
||||||
if (superfluous && ghost == None) {
|
|
||||||
ghost = MakeGhostDock(dock, dock->x_pos,
|
|
||||||
scr->scr_width - ICON_SIZE
|
|
||||||
- DOCK_EXTRA_SPACE - 1, dock->y_pos);
|
|
||||||
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 {
|
|
||||||
/* is on right */
|
|
||||||
if (ev.xmotion.x_root < dock->x_pos - ICON_SIZE) {
|
|
||||||
XMoveWindow(dpy, scr->dock_shadow, DOCK_EXTRA_SPACE, dock->y_pos);
|
|
||||||
if (superfluous && ghost == None) {
|
|
||||||
ghost = MakeGhostDock(dock, dock->x_pos,
|
|
||||||
DOCK_EXTRA_SPACE, dock->y_pos);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
now_on_right = (ev.xmotion.x_root > previous_x_pos + ICON_SIZE * 2);
|
||||||
|
}
|
||||||
|
if (now_on_right != dock->on_right_side)
|
||||||
|
{
|
||||||
|
dock->on_right_side = now_on_right;
|
||||||
|
swapDock(dock);
|
||||||
|
wArrangeIcons(scr, False);
|
||||||
|
}
|
||||||
|
// Also perform the vertical move
|
||||||
|
wScreenKeepInside(scr, &x, &y, ICON_SIZE, ICON_SIZE);
|
||||||
|
moveDock(dock, dock->x_pos, y);
|
||||||
break;
|
break;
|
||||||
case WM_DRAWER:
|
case WM_DRAWER:
|
||||||
{
|
{
|
||||||
@@ -3799,19 +3750,7 @@ static void handleDockMove(WDock *dock, WAppIcon *aicon, XEvent *event)
|
|||||||
shad_y);
|
shad_y);
|
||||||
XUnmapWindow(dpy, scr->dock_shadow);
|
XUnmapWindow(dpy, scr->dock_shadow);
|
||||||
moveDock(dock, shad_x, shad_y);
|
moveDock(dock, shad_x, shad_y);
|
||||||
} else {
|
XResizeWindow(dpy, scr->dock_shadow, ICON_SIZE, ICON_SIZE);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
done = 1;
|
done = 1;
|
||||||
break;
|
break;
|
||||||
@@ -4712,9 +4651,6 @@ static WDock * drawerRestoreState(WScreen *scr, WMPropList *drawer_state)
|
|||||||
x = scr->dock->x_pos;
|
x = scr->dock->x_pos;
|
||||||
}
|
}
|
||||||
y_index = (y - scr->dock->y_pos) / ICON_SIZE;
|
y_index = (y - scr->dock->y_pos) / ICON_SIZE;
|
||||||
if (y_index <= 0) {
|
|
||||||
y_index = 1;
|
|
||||||
}
|
|
||||||
if (y_index >= scr->dock->max_icons) {
|
if (y_index >= scr->dock->max_icons) {
|
||||||
/* Here we should do something more intelligent, since it
|
/* Here we should do something more intelligent, since it
|
||||||
* can happen even if the user hasn't hand-edited his
|
* can happen even if the user hasn't hand-edited his
|
||||||
|
|||||||
@@ -137,109 +137,6 @@ 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)
|
|
||||||
{
|
|
||||||
WScreen *scr = dock->screen_ptr;
|
|
||||||
WDrawerChain *dc;
|
|
||||||
WDock *drawer;
|
|
||||||
XImage *img;
|
|
||||||
RImage *back;
|
|
||||||
Pixmap pixmap;
|
|
||||||
int i, virtual_tiles, h, j, n;
|
|
||||||
unsigned long red_mask, green_mask, blue_mask;
|
|
||||||
|
|
||||||
virtual_tiles = 0;
|
|
||||||
for (i = 0; i < dock->max_icons; i++) {
|
|
||||||
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;
|
|
||||||
virtual_tiles = h / wPreferences.icon_size; /* The visible ones */
|
|
||||||
if (h % wPreferences.icon_size)
|
|
||||||
virtual_tiles++; /* There is one partially visible tile at end */
|
|
||||||
|
|
||||||
img = XGetImage(dpy, scr->root_win, dx, y, wPreferences.icon_size, h, 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; i < dock->max_icons; i++) {
|
|
||||||
if (dock->icon_array[i] != NULL && dock->icon_array[i]->yindex < virtual_tiles) {
|
|
||||||
Pixmap which;
|
|
||||||
j = dock->icon_array[i]->yindex * wPreferences.icon_size;
|
|
||||||
n = (h - j < wPreferences.icon_size) ? h - 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;
|
|
||||||
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);
|
|
||||||
|
|
||||||
RReleaseImage(back);
|
|
||||||
|
|
||||||
return pixmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pixmap MakeGhostIcon(WScreen * scr, Drawable drawable)
|
Pixmap MakeGhostIcon(WScreen * scr, Drawable drawable)
|
||||||
{
|
{
|
||||||
RImage *back;
|
RImage *back;
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include "dock.h"
|
#include "dock.h"
|
||||||
|
|
||||||
void DoKaboom(WScreen *scr, Window win, int x, int y);
|
void DoKaboom(WScreen *scr, Window win, int x, int y);
|
||||||
Pixmap MakeGhostDock(WDock *dock, int sx, int dx, int y);
|
|
||||||
Pixmap MakeGhostIcon(WScreen *scr, Drawable drawable);
|
Pixmap MakeGhostIcon(WScreen *scr, Drawable drawable);
|
||||||
void DoWindowBirth(WWindow *wwin);
|
void DoWindowBirth(WWindow *wwin);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user