From a10214a5023715dfa9bb0438fef8b700cc8a29a3 Mon Sep 17 00:00:00 2001 From: kojima Date: Thu, 28 Nov 2002 22:04:07 +0000 Subject: [PATCH] - Fixed sloppy focus bug (Pawel S. Veselov ) - Applied Xinerama patch (after fixes) from (Peter Zijlstra ) --- ChangeLog | 3 + FAQ | 33 ++++--- WINGs/Tests/wtest.c | 6 +- configure.ac | 10 +-- src/actions.c | 49 +++++++---- src/client.c | 3 + src/cycling.c | 14 ++- src/dialog.c | 25 ++---- src/dock.c | 101 ++++++++++++---------- src/dockedapp.c | 35 +++++--- src/event.c | 43 +++++----- src/funcs.h | 3 + src/menu.c | 161 ++++++++++++++++++---------------- src/moveres.c | 120 +++++++++++++++++++------- src/placement.c | 124 ++++++++++++++++----------- src/screen.c | 107 ++++++++++++++++++----- src/screen.h | 4 +- src/window.c | 106 +++++++++++++++++++++-- src/xinerama.c | 242 +++++++++++++++++++++++++++++++++------------------- src/xinerama.h | 12 ++- util/wmsetbg.c | 123 ++++++++++++++++++++++++++ 21 files changed, 915 insertions(+), 409 deletions(-) diff --git a/ChangeLog b/ChangeLog index b402dbec..296827cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -31,6 +31,9 @@ Changes since version 0.80.1: - Fixed wrlib to not accept too large images (fixes buffer overflow) - Patched FAQ (David Coe ) - Fixed bug with resizebars appearing out of nothing when reloading configs +- Fixed sloppy focus bug (Pawel S. Veselov ) +- Applied Xinerama patch (after fixes) from (Peter Zijlstra + ) Changes since version 0.80.0: ............................. diff --git a/FAQ b/FAQ index 3bdbe73f..f0fbb99b 100644 --- a/FAQ +++ b/FAQ @@ -1074,16 +1074,29 @@ to force the modification time into the future. 4.16 How can I set dock/clip to use single click to launch applications, instead of double click? ---------------------------------- -You cannot do this. This is because single click is used to select app-icons, -or to raise/lower the app-icon or the dock/clip. -If this is impelmented then you will be unable to select or raise/lower -dock/clip or app-icons, without also launching the application it represents. - -So don't ask for this to be implemented, because it will not be. Double -click is used for a reason, is not just some weird idea we got in a morning -when we wake up too early. - - +This question was officially answered as follows: + + You cannot do this. This is because single click is used to select + app-icons, or to raise/lower the app-icon or the dock/clip. If + this is impelmented then you will be unable to select or + raise/lower dock/clip or app-icons, without also launching the + application it represents. + + So don't ask for this to be implemented, because it will not + be. Double click is used for a reason, is not just some weird idea + we got in a morning when we wake up too early. + +Regardless of that, there is now an option in WPrefs, under "Expert +User Preferences," which allows you to set "Launch applications and +restore windows with a single click." (See the files contrib/README +and contrib/single_click.diff in the source package for details.) + +If you set that option, a left button single click will launch or +restore, rather than select, the app-icon. You can use other methods +(or temporarily turn the option off again) to select app-icons or +raise/lower the dock/clip. You can toggle the selected state of any +app-icon via its right button menu, and there are auto-raise and +keep-on-top options for the dock and clip. 4.18 How do I restore the configuration app to the dock? diff --git a/WINGs/Tests/wtest.c b/WINGs/Tests/wtest.c index 7f9f56d3..3808e24f 100644 --- a/WINGs/Tests/wtest.c +++ b/WINGs/Tests/wtest.c @@ -1303,14 +1303,15 @@ main(int argc, char **argv) */ + testTextField(scr); - testDragAndDrop(scr); - testText(scr); testFontPanel(scr); #if 0 + testText(scr); + testDragAndDrop(scr); testColorPanel(scr); testScrollView(scr); testTabView(scr); @@ -1322,7 +1323,6 @@ main(int argc, char **argv) testColorWell(scr); - testTextField(scr); testDragAndDrop(scr); testFontPanel(scr); diff --git a/configure.ac b/configure.ac index 448960c1..25380c47 100644 --- a/configure.ac +++ b/configure.ac @@ -15,7 +15,7 @@ AC_INIT(src/WindowMaker.h) -AM_INIT_AUTOMAKE(WindowMaker, 0.81.0) +AM_INIT_AUTOMAKE(WindowMaker, 0.81.2) AC_PROG_LIBTOOL @@ -526,10 +526,10 @@ fi dnl XINERAMA support dnl ================ -xinerama=no -#AC_ARG_ENABLE(xinerama, -#[ --disable-xinerama disable XInerama extension support], -# xinerama=$enableval, xinerama=yes) +xinerama=yes +AC_ARG_ENABLE(xinerama, +[ --disable-xinerama disable XInerama extension support], + xinerama=$enableval, xinerama=yes) if test "$xinerama" = yes; then AC_CHECK_LIB(Xinerama, XineramaQueryScreens, [XLIBS="-lXinerama $XLIBS" diff --git a/src/actions.c b/src/actions.c index 8f23c175..ec6eb6b6 100644 --- a/src/actions.c +++ b/src/actions.c @@ -412,7 +412,6 @@ wMaximizeWindow(WWindow *wwin, int directions) WArea usableArea = wwin->screen_ptr->totalUsableArea; WArea totalArea; - if (WFLAGP(wwin, no_resizable)) return; @@ -421,24 +420,28 @@ wMaximizeWindow(WWindow *wwin, int directions) totalArea.x2 = wwin->screen_ptr->scr_width; totalArea.y2 = wwin->screen_ptr->scr_height; -#ifdef XINERAMA if (wwin->screen_ptr->xine_count > 0 && !(directions & MAX_IGNORE_XINERAMA)) { WScreen *scr = wwin->screen_ptr; WMRect rect; + int head; + + /* XXX: + if ( keyboard) { + rect.pos.x = wwin->frame_x; + rect.pos.y = wwin->frame_y; + rect.size.width = wwin->frame->core->width; + rect.size.height = wwin->frame->core->height; + + head = wGetHeadForRect(scr, rect); + } else + */ + head = wGetHeadForPointerLocation(scr); - rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); - totalArea.x1 = rect.pos.x; - totalArea.y1 = rect.pos.y; - totalArea.x2 = totalArea.x1 + rect.size.width; - totalArea.y2 = totalArea.y1 + rect.size.height; + rect = wGetRectForHead(scr, head); - usableArea.x1 = WMAX(totalArea.x1, usableArea.x1); - usableArea.y1 = WMAX(totalArea.y1, usableArea.y1); - usableArea.x2 = WMIN(totalArea.x2, usableArea.x2); - usableArea.y2 = WMIN(totalArea.y2, usableArea.y2); + usableArea = wGetUsableAreaForHead(scr, head, &totalArea); } -#endif /* XINERAMA */ if (WFLAGP(wwin, full_maximize)) { usableArea = totalArea; @@ -1502,10 +1505,18 @@ wArrangeIcons(WScreen *scr, Bool arrangeAll) /* * Find out screen boundaries. */ - sx1 = 0; - sy1 = 0; - sx2 = scr->scr_width; - sy2 = scr->scr_height; + + /* + * Allows each head to have miniwindows + */ + WMRect rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); + + sx1 = rect.pos.x; + sy1 = rect.pos.y; + sw = rect.size.width; + sh = rect.size.height; + sx2 = sx1 + sw; + sy2 = sy1 + sh; if (scr->dock) { if (scr->dock->on_right_side) sx2 -= isize + DOCK_EXTRA_SPACE; @@ -1513,8 +1524,14 @@ wArrangeIcons(WScreen *scr, Bool arrangeAll) sx1 += isize + DOCK_EXTRA_SPACE; } +#if 0 sw = isize * (scr->scr_width/isize); sh = isize * (scr->scr_height/isize); +#else + sw = isize * (sw/isize); + sh = isize * (sh/isize); +#endif + fullW = (sx2-sx1)/isize; fullW = (sx2-sx1)/isize; fullH = (sy2-sy1)/isize; diff --git a/src/client.c b/src/client.c index d91eb619..7b6c60b5 100644 --- a/src/client.c +++ b/src/client.c @@ -47,6 +47,7 @@ #include "kwm.h" #endif + /****** Global Variables ******/ /* contexts */ @@ -179,6 +180,8 @@ wClientConfigure(WWindow *wwin, XConfigureRequestEvent *xcre) int nx, ny, nwidth, nheight; int ofs_x, ofs_y; +/* printf( "configure event: %d %d %d %d\n", xcre->x, xcre->y, xcre->width, xcre->height);*/ + if (wwin==NULL) { /* * configure a window that was not mapped by us diff --git a/src/cycling.c b/src/cycling.c index 51443d7f..182a3861 100644 --- a/src/cycling.c +++ b/src/cycling.c @@ -36,6 +36,7 @@ #include "actions.h" #include "stacking.h" #include "funcs.h" +#include "xinerama.h" /* Globals */ extern WPreferences wPreferences; @@ -303,9 +304,16 @@ StartWindozeCycle(WWindow *wwin, XEvent *event, Bool next) } scr->flags.doing_alt_tab = 0; - if (openedSwitchMenu) - OpenSwitchMenu(scr, scr->scr_width/2, scr->scr_height/2, False); - + if (openedSwitchMenu) { + /* + * place window in center of current head + */ + WMPoint center = wGetPointToCenterRectInHead(scr, + wGetHeadForPointerLocation(scr), + 0, 0); + OpenSwitchMenu(scr, center.x, center.y, False); + } + if (somethingElse) { WMHandleEvent(&ev); } diff --git a/src/dialog.c b/src/dialog.c index 4ece8359..0d987ef5 100644 --- a/src/dialog.c +++ b/src/dialog.c @@ -69,23 +69,10 @@ extern WPreferences wPreferences; static WMPoint getCenter(WScreen *scr, int width, int height) { - WMPoint pt; - -#ifdef XINERAMA - WMRect rect; - - rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); - - pt.x = rect.pos.x + (rect.size.width - width)/2; - pt.y = rect.pos.y + (rect.size.height - height)/2; -#else - pt.x = (scr->scr_width - width) / 2; - pt.y = (scr->scr_height - height) / 2; -#endif - - return pt; + return wGetPointToCenterRectInHead(scr, + wGetHeadForPointerLocation(scr), + width, height); } - int @@ -146,6 +133,7 @@ wExitDialog(WScreen *scr, char *title, char *message, WMButton *saveSessionBtn; Window parent; WWindow *wwin; + WMPoint center; int result; panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message, @@ -165,9 +153,10 @@ wExitDialog(WScreen *scr, char *title, char *message, XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0); + center = getCenter(scr, 400, 180); wwin = wManageInternalWindow(scr, parent, None, NULL, - (scr->scr_width - 400)/2, - (scr->scr_height - 180)/2, 400, 180); + center.x, center.y, 400, 180); + wwin->client_leader = WMWidgetXID(panel->win); WMMapWidget(panel->win); diff --git a/src/dock.c b/src/dock.c index 168aa809..959f24d9 100644 --- a/src/dock.c +++ b/src/dock.c @@ -54,7 +54,7 @@ #include "framewin.h" #include "superfluous.h" #include "wsound.h" - +#include "xinerama.h" @@ -1712,20 +1712,22 @@ wClipRestoreState(WScreen *scr, WMPropList *clip_state) if (!WMIsPLString(value)) COMPLAIN("Position"); else { + WMRect rect; + int flags; + if (sscanf(WMGetFromPLString(value), "%i,%i", &icon->x_pos, &icon->y_pos)!=2) COMPLAIN("Position"); /* check position sanity */ - if (icon->y_pos < 0) - icon->y_pos = 0; - else if (icon->y_pos > scr->scr_height-ICON_SIZE) - icon->y_pos = scr->scr_height-ICON_SIZE; - - if (icon->x_pos < 0) - icon->x_pos = 0; - else if (icon->x_pos > scr->scr_width-ICON_SIZE) - icon->x_pos = scr->scr_width-ICON_SIZE; + rect.pos.x = icon->x_pos; + rect.pos.y = icon->y_pos; + rect.size.width = rect.size.height = ICON_SIZE; + + wGetRectPlacementInfo(scr, rect, &flags); + if (flags & (XFLAG_DEAD | XFLAG_PARTIAL)) + wScreenKeepInside(scr, &icon->x_pos, &icon->y_pos, + ICON_SIZE, ICON_SIZE); } } @@ -1772,15 +1774,23 @@ wDockRestoreState(WScreen *scr, WMPropList *dock_state, int type) if (!WMIsPLString(value)) COMPLAIN("Position"); else { + WMRect rect; + int flags; + if (sscanf(WMGetFromPLString(value), "%i,%i", &dock->x_pos, &dock->y_pos)!=2) COMPLAIN("Position"); /* check position sanity */ - if (dock->y_pos < 0) - dock->y_pos = 0; - else if (dock->y_pos > scr->scr_height-ICON_SIZE) - dock->y_pos = scr->scr_height - ICON_SIZE; + 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); + } /* This is no more needed. ??? */ if (type == WM_CLIP) { @@ -2464,6 +2474,7 @@ wDockSnapIcon(WDock *dock, WAppIcon *icon, int req_x, int req_y, WAppIcon *nicon = NULL; int max_y_icons, max_x_icons; + /* TODO: XINERAMA, for these */ max_x_icons = scr->scr_width/ICON_SIZE; max_y_icons = scr->scr_height/ICON_SIZE-1; @@ -2491,11 +2502,18 @@ wDockSnapIcon(WDock *dock, WAppIcon *icon, int req_x, int req_y, ex_x = (req_x + offset - dx)/ICON_SIZE; /* check if the icon is outside the screen boundaries */ - if (dx + ex_x*ICON_SIZE < -ICON_SIZE+2 || - dx + ex_x*ICON_SIZE >= scr->scr_width-1 || - dy + ex_y*ICON_SIZE < -ICON_SIZE+2 || - dy + ex_y*ICON_SIZE >= scr->scr_height-1) - return False; + { + WMRect rect; + int flags; + + rect.pos.x = dx + ex_x*ICON_SIZE; + rect.pos.y = dy + ex_y*ICON_SIZE; + rect.size.width = rect.size.height = ICON_SIZE; + + wGetRectPlacementInfo(scr, rect, &flags); + if (flags & (XFLAG_DEAD | XFLAG_PARTIAL)) + return False; + } if (dock->type == WM_DOCK) { if (icon->dock != dock && ex_x != 0) @@ -2623,9 +2641,17 @@ wDockSnapIcon(WDock *dock, WAppIcon *icon, int req_x, int req_y, } -#define ON_SCREEN(x, y, sx, ex, sy, ey) \ - ((((x)+ICON_SIZE/2) >= (sx)) && (((y)+ICON_SIZE/2) >= (sy)) && \ - (((x) + (ICON_SIZE/2)) <= (ex)) && (((y) + (ICON_SIZE/2)) <= ey)) +static int onScreen(WScreen *scr, int x, int y, int sx, int ex, int sy, int ey) +{ + WMRect rect = { (x), (y), (ICON_SIZE), (ICON_SIZE) }; + int flags; + + wGetRectPlacementInfo(scr, rect, &flags); + + return !(flags & (XFLAG_DEAD | XFLAG_PARTIAL)); +} + +#define ON_SCREEN(x, y, sx, ex, sy, ey) onScreen(scr, x, y, sx, ex, sy, ey) /* @@ -3662,22 +3688,10 @@ handleDockMove(WDock *dock, WAppIcon *aicon, XEvent *event) break; } if (dock->type == WM_CLIP) { - if (ev.xmotion.x_root - ofs_x < 0) { - x = 0; - } else if (ev.xmotion.x_root - ofs_x + ICON_SIZE > - scr->scr_width) { - x = scr->scr_width - ICON_SIZE; - } else { - x = ev.xmotion.x_root - ofs_x; - } - if (ev.xmotion.y_root - ofs_y < 0) { - y = 0; - } else if (ev.xmotion.y_root - ofs_y + ICON_SIZE > - scr->scr_height) { - y = scr->scr_height - ICON_SIZE; - } else { - y = ev.xmotion.y_root - ofs_y; - } + x = ev.xmotion.x_root - ofs_x; + y = ev.xmotion.y_root - ofs_y; + wScreenKeepInside(scr, &x, &y, ICON_SIZE, ICON_SIZE); + moveDock(dock, x, y); } else { /* move vertically if pointer is inside the dock*/ @@ -3686,14 +3700,9 @@ handleDockMove(WDock *dock, WAppIcon *aicon, XEvent *event) || (!dock->on_right_side && ev.xmotion.x_root <= dock->x_pos + ICON_SIZE*2)) { - if (ev.xmotion.y_root - ofs_y < 0) { - y = 0; - } else if (ev.xmotion.y_root - ofs_y + ICON_SIZE > - scr->scr_height) { - y = scr->scr_height - ICON_SIZE; - } else { - y = ev.xmotion.y_root - ofs_y; - } + 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 */ diff --git a/src/dockedapp.c b/src/dockedapp.c index 7f327840..2146d724 100644 --- a/src/dockedapp.c +++ b/src/dockedapp.c @@ -38,6 +38,7 @@ #include "funcs.h" #include "defaults.h" #include "framewin.h" +#include "xinerama.h" /**** Global variables ****/ @@ -448,20 +449,28 @@ ShowDockAppSettingsPanel(WAppIcon *aicon) XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0); - y = aicon->y_pos; - if (y < 0) - y = 0; - else if (y + PHEIGHT > scr->scr_height) - y = scr->scr_height - PHEIGHT - 30; - - if (aicon->dock && aicon->dock->type == WM_DOCK) { - if (aicon->dock->on_right_side) - x = scr->scr_width/2; - else - x = scr->scr_width/2 - PWIDTH - 2; - } else { - x = (scr->scr_width - PWIDTH)/2; + /* + * make things relative to head + */ + { + WMRect rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); + + y = aicon->y_pos; + if (y < 0) + y = 0; + else if (y + PHEIGHT > rect.pos.y + rect.size.height) + 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; + } else { + x = rect.pos.x + (rect.size.width - PWIDTH)/2; + } } + panel->wwin = wManageInternalWindow(scr, parent, None, _("Docked Application Settings"), x, y, PWIDTH, PHEIGHT); diff --git a/src/event.c b/src/event.c index f3d4f06f..5214aad4 100644 --- a/src/event.c +++ b/src/event.c @@ -58,6 +58,7 @@ #include "framewin.h" #include "properties.h" #include "balloon.h" +#include "xinerama.h" #ifdef GNOME_STUFF # include "gnome.h" @@ -1140,11 +1141,11 @@ handleEnterNotify(XEvent *event) } if (event->xcrossing.window == event->xcrossing.root - && event->xcrossing.detail == NotifyNormal - && event->xcrossing.detail != NotifyInferior + && (event->xcrossing.mode == NotifyNormal || + event->xcrossing.mode == NotifyUngrab ) + && event->xcrossing.detail == NotifyInferior && wPreferences.focus_mode != WKF_CLICK) { - - wSetFocusTo(scr, scr->focused_window); + wSetFocusTo(scr, NULL); } #ifdef BALLOON_TEXT @@ -1163,15 +1164,6 @@ handleLeaveNotify(XEvent *event) if(desc->handle_leavenotify) (*desc->handle_leavenotify)(desc, event); } - if (event->xcrossing.window == event->xcrossing.root - && event->xcrossing.mode == NotifyNormal - && event->xcrossing.detail != NotifyInferior - && wPreferences.focus_mode != WKF_CLICK) { - - WScreen *scr = wScreenForRootWindow(event->xcrossing.root); - - wSetFocusTo(scr, NULL); - } } @@ -1403,10 +1395,16 @@ handleKeyPress(XEvent *event) #ifndef LITE case WKBD_ROOTMENU: /*OpenRootMenu(scr, event->xkey.x_root, event->xkey.y_root, True);*/ - OpenRootMenu(scr, scr->scr_width/2, scr->scr_height/2, True); + { + WMRect rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); + OpenRootMenu(scr, rect.pos.x + rect.size.width/2, rect.pos.y + rect.size.height/2, True); + } break; case WKBD_WINDOWLIST: - OpenSwitchMenu(scr, scr->scr_width/2, scr->scr_height/2, True); + { + WMRect rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); + OpenSwitchMenu(scr, rect.pos.x + rect.size.width/2, rect.pos.y + rect.size.height/2, True); + } break; #endif /* !LITE */ case WKBD_WINDOWMENU: @@ -1719,15 +1717,18 @@ handleKeyPress(XEvent *event) static void handleMotionNotify(XEvent *event) { - WMenu *menu; WScreen *scr = wScreenForRootWindow(event->xmotion.root); if (wPreferences.scrollable_menus) { - if (scr->flags.jump_back_pending || - event->xmotion.x_root <= 1 || - event->xmotion.x_root >= (scr->scr_width - 2) || - event->xmotion.y_root <= 1 || - event->xmotion.y_root >= (scr->scr_height - 2)) { + WMPoint p = { event->xmotion.x_root, event->xmotion.y_root }; + WMRect rect = wGetRectForHead(scr, wGetHeadForPoint(scr, p)); + + if (scr->flags.jump_back_pending || + p.x <= (rect.pos.x + 1) || + p.x >= (rect.pos.x + rect.size.width - 2) || + p.y <= (rect.pos.y + 1) || + p.y >= (rect.pos.y + rect.size.height - 2)) { + WMenu *menu; #ifdef DEBUG L("pointer at screen edge"); #endif diff --git a/src/funcs.h b/src/funcs.h index 78f2e410..1fbff6cd 100644 --- a/src/funcs.h +++ b/src/funcs.h @@ -85,6 +85,9 @@ Pixmap LoadIcon(WScreen *scr, char *path, char *mask, int title_height); void PlaceIcon(WScreen *scr, int *x_ret, int *y_ret); +int calcIntersectionArea(int x1, int y1, int w1, int h1, + int x2, int y2, int w2, int h2); + void PlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, unsigned int width, unsigned int height); diff --git a/src/menu.c b/src/menu.c index 6f655904..128b1f8b 100644 --- a/src/menu.c +++ b/src/menu.c @@ -42,6 +42,7 @@ #include "funcs.h" #include "stacking.h" #include "text.h" +#include "xinerama.h" /****** Global Variables ******/ @@ -869,6 +870,7 @@ makeVisible(WMenu *menu) { WScreen *scr = menu->frame->screen_ptr; int x1, y1, x2, y2, new_x, new_y, move; + WMRect rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); if (menu->entry_no<0) return; @@ -882,20 +884,21 @@ makeVisible(WMenu *menu) new_y = y1; move = 0; - if (x1 < 0) { - new_x = 0; - move = 1; - } else if (x2 >= scr->scr_width) { - new_x = scr->scr_width - MENUW(menu) - 1; - move = 1; - } - if (y1 < 0) { - new_y = 0; - move = 1; - } else if (y2 >= scr->scr_height) { - new_y = scr->scr_height - menu->entry_height - 1; - move = 1; + if (x1 < rect.pos.x) { + new_x = rect.pos.x; + move = 1; + } else if (x2 >= rect.pos.x + rect.size.width) { + new_x = rect.pos.x + rect.size.width - MENUW(menu) - 1; + move = 1; + } + + if (y1 < rect.pos.y) { + new_y = rect.pos.y; + move = 1; + } else if (y2 >= rect.pos.y + rect.size.height) { + new_y = rect.pos.y + rect.size.height - menu->entry_height - 1; + move = 1; } new_y = new_y - menu->frame->top_width @@ -943,8 +946,8 @@ keyboardMenu(WMenu *menu) int old_pos_x = menu->frame_x; int old_pos_y = menu->frame_y; int new_x = old_pos_x, new_y = old_pos_y; - int scr_width = menu->frame->screen_ptr->scr_width; - int scr_height = menu->frame->screen_ptr->scr_height; + WMRect rect = wGetRectForHead(menu->frame->screen_ptr, + wGetHeadForPointerLocation(menu->frame->screen_ptr)); if (menu->flags.editing) return False; @@ -953,11 +956,12 @@ keyboardMenu(WMenu *menu) XGrabKeyboard(dpy, menu->frame->core->window, True, GrabModeAsync, GrabModeAsync, CurrentTime); - if (menu->frame_y+menu->frame->top_width >= scr_height) - new_y = scr_height - menu->frame->top_width; - - if (menu->frame_x+MENUW(menu) >= scr_width) - new_x = scr_width-MENUW(menu)-1; + + if (menu->frame_y+menu->frame->top_width >= rect.pos.y + rect.size.height) + new_y = rect.pos.y + rect.size.height - menu->frame->top_width; + + if (menu->frame_x+MENUW(menu) >= rect.pos.x + rect.size.width) + new_x = rect.pos.x + rect.size.width - MENUW(menu) - 1; move_menus(menu, new_x, new_y); @@ -1132,8 +1136,8 @@ keyboardMenu(WMenu *menu) void wMenuMapAt(WMenu *menu, int x, int y, int keyboard) { - int scr_width = menu->frame->screen_ptr->scr_width; - int scr_height = menu->frame->screen_ptr->scr_height; + WMRect rect = wGetRectForHead(menu->frame->screen_ptr, + wGetHeadForPointerLocation(menu->frame->screen_ptr)); if (!menu->flags.realized) { menu->flags.realized=1; @@ -1141,12 +1145,12 @@ wMenuMapAt(WMenu *menu, int x, int y, int keyboard) } if (!menu->flags.mapped) { if (wPreferences.wrap_menus) { - if (x<0) x = 0; - if (y<0) y = 0; - if (x+MENUW(menu) > scr_width) - x = scr_width - MENUW(menu); - if (y+MENUH(menu) > scr_height) - y = scr_height - MENUH(menu); + if (x rect.pos.x + rect.size.width) + x = rect.pos.x + rect.size.width - MENUW(menu); + if (y+MENUH(menu) > rect.pos.y + rect.size.height) + y = rect.pos.y + rect.size.height - MENUH(menu); } XMoveWindow(dpy, menu->frame->core->window, x, y); @@ -1618,39 +1622,40 @@ getScrollAmount(WMenu *menu, int *hamount, int *vamount) int menuY1 = menu->frame_y; int menuX2 = menu->frame_x + MENUW(menu); int menuY2 = menu->frame_y + MENUH(menu); - int screenW = scr->scr_width; - int screenH = scr->scr_height; int xroot, yroot; + WMRect rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); + *hamount = 0; *vamount = 0; getPointerPosition(scr, &xroot, &yroot); - - if (xroot <= 1 && menuX1 < 0) { - /* scroll to the right */ - *hamount = WMIN(MENU_SCROLL_STEP, abs(menuX1)); - - } else if (xroot >= screenW-2 && menuX2 > screenW-1) { - /* scroll to the left */ - *hamount = WMIN(MENU_SCROLL_STEP, abs(menuX2-screenW-1)); - - if (*hamount==0) - *hamount = 1; - - *hamount = -*hamount; - } - - if (yroot <= 1 && menuY1 < 0) { - /* scroll down */ - *vamount = WMIN(MENU_SCROLL_STEP, abs(menuY1)); - - } else if (yroot >= screenH-2 && menuY2 > screenH-1) { - /* scroll up */ - *vamount = WMIN(MENU_SCROLL_STEP, abs(menuY2-screenH-2)); - - *vamount = -*vamount; + if (xroot <= (rect.pos.x + 1) && menuX1 < rect.pos.x) { + /* scroll to the right */ + *hamount = WMIN(MENU_SCROLL_STEP, abs(menuX1)); + + } else if (xroot >= (rect.pos.x + rect.size.width - 2) && + menuX2 > (rect.pos.x + rect.size.width - 1)) { + /* scroll to the left */ + *hamount = WMIN(MENU_SCROLL_STEP, abs(menuX2-rect.pos.x-rect.size.width-1)); + + if (*hamount==0) + *hamount = 1; + + *hamount = -*hamount; + } + + if (yroot <= (rect.pos.y + 1) && menuY1 < rect.pos.y) { + /* scroll down */ + *vamount = WMIN(MENU_SCROLL_STEP, abs(menuY1)); + + } else if (yroot >= (rect.pos.y + rect.size.height - 2) && + menuY2 > (rect.pos.y + rect.size.height - 1)) { + /* scroll up */ + *vamount = WMIN(MENU_SCROLL_STEP, abs(menuY2-rect.pos.y-rect.size.height-2)); + + *vamount = -*vamount; } } @@ -1740,16 +1745,19 @@ isPointNearBoder(WMenu *menu, int x, int y) int menuY1 = menu->frame_y; int menuX2 = menu->frame_x + MENUW(menu); int menuY2 = menu->frame_y + MENUH(menu); - int scrXe = menu->menu->screen_ptr->scr_width-1; - int scrYe = menu->menu->screen_ptr->scr_height-1; int flag = 0; - - if (x >= menuX1 && x <= menuX2 && (y < MENU_SCROLL_BORDER - || y > scrYe-MENU_SCROLL_BORDER)) - flag = 1; - else if (y >= menuY1 && y <= menuY2 && (x < MENU_SCROLL_BORDER - || x > scrXe-MENU_SCROLL_BORDER)) - flag = 1; + /* XXX: handle screen joins proper !! */ + WMRect rect = wGetRectForHead(menu->frame->screen_ptr, + wGetHeadForPoint(menu->frame->screen_ptr, (WMPoint){ x, y})); + + if (x >= menuX1 && x <= menuX2 && + (y < rect.pos.y + MENU_SCROLL_BORDER || + y >= rect.pos.y + rect.size.height + MENU_SCROLL_BORDER)) + flag = 1; + else if (y >= menuY1 && y <= menuY2 && + (x < rect.pos.x + MENU_SCROLL_BORDER || + x >= rect.pos.x + rect.size.width + MENU_SCROLL_BORDER)) + flag = 1; return flag; } @@ -1803,6 +1811,7 @@ wMenuScroll(WMenu *menu, XEvent *event) while(!done) { int x, y, on_border, on_x_edge, on_y_edge, on_title; + WMRect rect; WMNextEvent(dpy, &ev); switch (ev.type) { @@ -1823,8 +1832,9 @@ wMenuScroll(WMenu *menu, XEvent *event) break; } - on_x_edge = x <= 1 || x >= scr->scr_width - 2; - on_y_edge = y <= 1 || y >= scr->scr_height - 2; + rect = wGetRectForHead(scr, wGetHeadForPoint(scr, (WMPoint){ x, y })); + on_x_edge = x <= rect.pos.x + 1 || x >= rect.pos.x + rect.size.width - 2; + on_y_edge = y <= rect.pos.y + 1 || y >= rect.pos.y + rect.size.height - 2; on_border = on_x_edge || on_y_edge; if (!on_border && !jump_back) { @@ -2631,15 +2641,17 @@ restoreMenu(WScreen *scr, WMPropList *menu, int which) if (pmenu) { int width = MENUW(pmenu); int height = MENUH(pmenu); + WMRect rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); if (lowered) { changeMenuLevels(pmenu, True); } - x = (x < -width) ? 0 : x; - x = (x > scr->scr_width) ? scr->scr_width - width : x; - y = (y < 0) ? 0 : y; - y = (y > scr->scr_height) ? scr->scr_height - height : y; + if (x < rect.pos.x - width) x = rect.pos.x; + if (x > rect.pos.x + rect.size.width) x = rect.pos.x + rect.size.width - width; + if (y < rect.pos.y) y = rect.pos.y; + if (y > rect.pos.y + rect.size.height) y = rect.pos.y + rect.size.height - height; + wMenuMove(pmenu, x, y, True); pmenu->flags.buttoned = 1; wFrameWindowShowButton(pmenu->frame, WFF_RIGHT_BUTTON); @@ -2671,6 +2683,7 @@ restoreMenuRecurs(WScreen *scr, WMPropList *menus, WMenu *menu, char *path) if (!menu->flags.mapped) { int width = MENUW(menu); int height = MENUH(menu); + WMRect rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); wMenuMapAt(menu, x, y, False); @@ -2686,10 +2699,12 @@ restoreMenuRecurs(WScreen *scr, WMPropList *menus, WMenu *menu, char *path) if (lowered) { changeMenuLevels(menu, True); } - x = (x < -width) ? 0 : x; - x = (x > scr->scr_width) ? scr->scr_width - width : x; - y = (y < 0) ? 0 : y; - y = (y > scr->scr_height) ? scr->scr_height - height : y; + + if (x < rect.pos.x - width) x = rect.pos.x; + if (x > rect.pos.x + rect.size.width) x = rect.pos.x + rect.size.width - width; + if (y < rect.pos.y) y = rect.pos.y; + if (y > rect.pos.y + rect.size.height) y = rect.pos.y + rect.size.height - height; + wMenuMove(menu, x, y, True); menu->flags.buttoned = 1; wFrameWindowShowButton(menu->frame, WFF_RIGHT_BUTTON); diff --git a/src/moveres.c b/src/moveres.c index b8238ae6..0e72fe55 100644 --- a/src/moveres.c +++ b/src/moveres.c @@ -41,6 +41,8 @@ #include "workspace.h" #include "geomview.h" +#include "screen.h" +#include "xinerama.h" #include @@ -110,19 +112,45 @@ moveGeometryDisplayCentered(WScreen *scr, int x, int y) { unsigned int w = WMWidgetWidth(scr->gview); unsigned int h = WMWidgetHeight(scr->gview); + unsigned int x1 = 0, y1 = 0, x2 = scr->scr_width, y2 = scr->scr_height; + x -= w / 2; y -= h / 2; - if (x < 1) - x = 1; - else if (x > (scr->scr_width - w - 3)) - x = scr->scr_width - w - 3; - - if (y < 1) - y = 1; - else if (y > (scr->scr_height - h - 3)) - y = scr->scr_height - h - 3; + /* + * dead area check + */ + if (scr->xine_count) { + WMRect rect; + int head, flags; + + rect.pos.x = x; + rect.pos.y = y; + rect.size.width = w; + rect.size.height = h; + + head = wGetRectPlacementInfo(scr, rect, &flags); + + if (flags & (XFLAG_DEAD | XFLAG_PARTIAL)) { + rect = wGetRectForHead(scr, head); + x1 = rect.pos.x; + y1 = rect.pos.y; + x2 = x1 + rect.size.width; + y2 = y1 + rect.size.height; + } + } + + if (x < x1 + 1) + x = x1 + 1; + else if (x > (x2 - w)) + x = x2 - w; + + if (y < y1 + 1) + y = y1 + 1; + else if (y > (y2 - h)) + y = y2 - h; + WMMoveWidget(scr->gview, x, y); } @@ -178,8 +206,10 @@ cyclePositionDisplay(WWindow *wwin, int x, int y, int w, int h) WMUnmapWidget(scr->gview); } else { if (wPreferences.move_display == WDIS_CENTER) { - moveGeometryDisplayCentered(scr, - scr->scr_width/2, scr->scr_height/2); + WMRect rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); + moveGeometryDisplayCentered(scr, + rect.pos.x + rect.size.width/2, + rect.pos.y + rect.size.width/2); } else if (wPreferences.move_display == WDIS_TOPLEFT) { moveGeometryDisplayCentered(scr, 1, 1); } else if (wPreferences.move_display == WDIS_FRAME_CENTER) { @@ -199,8 +229,10 @@ mapPositionDisplay(WWindow *wwin, int x, int y, int w, int h) || wPreferences.move_display == WDIS_NONE) { return; } else if (wPreferences.move_display == WDIS_CENTER) { - moveGeometryDisplayCentered(scr, scr->scr_width / 2, - scr->scr_height / 2); + WMRect rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); + moveGeometryDisplayCentered(scr, + rect.pos.x + rect.size.width/2, + rect.pos.y + rect.size.width/2); } else if (wPreferences.move_display == WDIS_TOPLEFT) { moveGeometryDisplayCentered(scr, 1, 1); } else if (wPreferences.move_display == WDIS_FRAME_CENTER) { @@ -383,8 +415,10 @@ cycleGeometryDisplay(WWindow *wwin, int x, int y, int w, int h, int dir) WMUnmapWidget(scr->gview); } else { if (wPreferences.size_display == WDIS_CENTER) { - moveGeometryDisplayCentered(scr, - scr->scr_width / 2, scr->scr_height / 2); + WMRect rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); + moveGeometryDisplayCentered(scr, + rect.pos.x + rect.size.width/2, + rect.pos.y + rect.size.width/2); } else if (wPreferences.size_display == WDIS_TOPLEFT) { moveGeometryDisplayCentered(scr, 1, 1); } else if (wPreferences.size_display == WDIS_FRAME_CENTER) { @@ -406,8 +440,10 @@ mapGeometryDisplay(WWindow *wwin, int x, int y, int w, int h) return; if (wPreferences.size_display == WDIS_CENTER) { - moveGeometryDisplayCentered(scr, scr->scr_width / 2, - scr->scr_height / 2); + WMRect rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); + moveGeometryDisplayCentered(scr, + rect.pos.x + rect.size.width/2, + rect.pos.y + rect.size.width/2); } else if (wPreferences.size_display == WDIS_TOPLEFT) { moveGeometryDisplayCentered(scr, 1, 1); } else if (wPreferences.size_display == WDIS_FRAME_CENTER) { @@ -423,9 +459,8 @@ static void doWindowMove(WWindow *wwin, WMArray *array, int dx, int dy) { WWindow *tmpw; + WScreen *scr = wwin->screen_ptr; int x, y; - int scr_width = wwin->screen_ptr->scr_width; - int scr_height = wwin->screen_ptr->scr_height; if (!array || !WMGetArrayItemCount(array)) { wWindowMove(wwin, wwin->frame_x + dx, wwin->frame_y + dy); @@ -436,17 +471,23 @@ doWindowMove(WWindow *wwin, WMArray *array, int dx, int dy) x = tmpw->frame_x + dx; y = tmpw->frame_y + dy; +#if 1 /* XXX: with xinerama patch was #if 0, check this */ /* don't let windows become unreachable */ if (x + (int)tmpw->frame->core->width < 20) x = 20 - (int)tmpw->frame->core->width; - else if (x + 20 > scr_width) - x = scr_width - 20; + else if (x + 20 > scr->scr_width) + x = scr->scr_width - 20; if (y + (int)tmpw->frame->core->height < 20) y = 20 - (int)tmpw->frame->core->height; - else if (y + 20 > scr_height) - y = scr_height - 20; + else if (y + 20 > scr->scr_height) + y = scr->scr_height - 20; +#else + wScreenBringInside(scr, &x, &y, + (int)tmpw->frame->core->width, + (int)tmpw->frame->core->height); +#endif wWindowMove(tmpw, x, y); } @@ -509,7 +550,7 @@ drawFrames(WWindow *wwin, WMArray *array, int dx, int dy) y = tmpw->frame_y + dy; /* don't let windows become unreachable */ - +#if 1 /* XXX: was 0 in XINERAMA patch, check */ if (x + (int)tmpw->frame->core->width < 20) x = 20 - (int)tmpw->frame->core->width; else if (x + 20 > scr_width) @@ -520,6 +561,12 @@ drawFrames(WWindow *wwin, WMArray *array, int dx, int dy) else if (y + 20 > scr_height) y = scr_height - 20; +#else + wScreenBringInside(wwin->screen_ptr, &x, &y, + (int)tmpw->frame->core->width, + (int)tmpw->frame->core->height); +#endif + drawTransparentFrame(tmpw, x, y, tmpw->frame->core->width, tmpw->frame->core->height); } @@ -981,10 +1028,16 @@ updateWindowPosition(WWindow *wwin, MoveData *data, Bool doResistance, if (dx || dy) { int i; /* window is the leftmost window: check against screen edge */ - l_edge = scr->totalUsableArea.x1; - r_edge = scr->totalUsableArea.x2 + resist; - edge_l = scr->totalUsableArea.x1 - resist; - edge_r = scr->totalUsableArea.x2; + + /* + * Add inter head resistance 1/2 (if needed) + */ + WMRect rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); + + l_edge = WMAX(scr->totalUsableArea.x1, rect.pos.x); + edge_l = l_edge - resist; + edge_r = WMIN(scr->totalUsableArea.x2, rect.pos.x + rect.size.width); + r_edge = edge_r + resist; /* 1 */ if ((data->rightIndex >= 0) && (data->rightIndex <= data->count)) { @@ -1080,10 +1133,13 @@ updateWindowPosition(WWindow *wwin, MoveData *data, Bool doResistance, } /* VeRT */ - t_edge = scr->totalUsableArea.y1; - b_edge = scr->totalUsableArea.y2 + resist; - edge_t = scr->totalUsableArea.y1 - resist; - edge_b = scr->totalUsableArea.y2; + /* + * Add inter head resistance 2/2 (if needed) + */ + t_edge = WMAX(scr->totalUsableArea.y1, rect.pos.y); + edge_t = t_edge - resist; + edge_b = WMIN(scr->totalUsableArea.y2, rect.pos.y + rect.size.height); + b_edge = edge_b + resist; if ((data->bottomIndex >= 0) && (data->bottomIndex <= data->count)) { WWindow *looprw; diff --git a/src/placement.c b/src/placement.c index 77fa228d..6edfbde0 100644 --- a/src/placement.c +++ b/src/placement.c @@ -39,6 +39,7 @@ #include "application.h" #include "appicon.h" #include "dock.h" +#include "xinerama.h" extern WPreferences wPreferences; @@ -140,14 +141,22 @@ PlaceIcon(WScreen *scr, int *x_ret, int *y_ret) int isize = wPreferences.icon_size; int done = 0; WMBagIterator iter; - /* * Find out screen boundaries. */ - sx1 = 0; - sy1 = 0; - sx2 = scr->scr_width; - sy2 = scr->scr_height; + + /* + * Allows each head to have miniwindows + */ + WMRect rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr)); + + sx1 = rect.pos.x; + sy1 = rect.pos.y; + sw = rect.size.width; + sh = rect.size.height; + sx2 = sx1 + sw; + sy2 = sy1 + sh; + if (scr->dock) { if (scr->dock->on_right_side) sx2 -= isize + DOCK_EXTRA_SPACE; @@ -155,8 +164,8 @@ PlaceIcon(WScreen *scr, int *x_ret, int *y_ret) sx1 += isize + DOCK_EXTRA_SPACE; } - sw = isize * (scr->scr_width/isize); - sh = isize * (scr->scr_height/isize); + sw = isize * (sw/isize); + sh = isize * (sh/isize); fullW = (sx2-sx1)/isize; fullH = (sy2-sy1)/isize; @@ -284,9 +293,10 @@ calcIntersectionLength(int p1, int l1, int p2, int l2) /* * This function calculates the area of the intersection of two rectangles. */ -static int + +int calcIntersectionArea(int x1, int y1, int w1, int h1, - int x2, int y2, int w2, int h2) + int x2, int y2, int w2, int h2) { return calcIntersectionLength(x1, w1, x2, w2) * calcIntersectionLength(y1, h1, y2, h2); @@ -337,7 +347,8 @@ calcSumOfCoveredAreas(WWindow *wwin, int x, int y, int w, int h) static void smartPlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, - unsigned int width, unsigned int height) + unsigned int width, unsigned int height, + WArea usableArea) { WScreen *scr = wwin->screen_ptr; int test_x = 0, test_y = Y_ORIGIN(scr); @@ -346,7 +357,6 @@ smartPlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, int min_isect, min_isect_x, min_isect_y; int sum_isect; int extra_height; - WArea usableArea = scr->totalUsableArea; if (wwin->frame) extra_height = wwin->frame->top_width + wwin->frame->bottom_width; @@ -413,7 +423,8 @@ smartPlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, static Bool autoPlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, - unsigned int width, unsigned int height, int tryCount) + unsigned int width, unsigned int height, int tryCount, + WArea usableArea) { WScreen *scr = wwin->screen_ptr; int test_x = 0, test_y = Y_ORIGIN(scr); @@ -421,7 +432,7 @@ autoPlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, int swidth, sx; WWindow *test_window; int extra_height; - WArea usableArea = scr->totalUsableArea; + if (wwin->frame) extra_height = wwin->frame->top_width + wwin->frame->bottom_width + 2; @@ -435,8 +446,7 @@ autoPlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, height += extra_height; - while (((test_y + height) < (scr->scr_height)) && (!loc_ok)) { - + while (((test_y + height) < (usableArea.y2 - usableArea.y1)) && !loc_ok) { test_x = sx; while (((test_x + width) < swidth) && (!loc_ok)) { @@ -527,10 +537,11 @@ autoPlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, static void cascadeWindow(WScreen *scr, WWindow *wwin, int *x_ret, int *y_ret, - unsigned int width, unsigned int height, int h) + unsigned int width, unsigned int height, int h, + WArea usableArea) { unsigned int extra_height; - WArea usableArea = scr->totalUsableArea; + if (wwin->frame) extra_height = wwin->frame->top_width + wwin->frame->bottom_width; @@ -549,26 +560,53 @@ cascadeWindow(WScreen *scr, WWindow *wwin, int *x_ret, int *y_ret, } +static void +randomPlaceWindow(WScreen *scr, WWindow *wwin, int *x_ret, int *y_ret, + unsigned int width, unsigned int height, + WArea usableArea) +{ + int w, h, extra_height; + + if (wwin->frame) + extra_height = wwin->frame->top_width + wwin->frame->bottom_width + 2; + else + extra_height = 24; /* random value */ + + w = ((usableArea.x2-X_ORIGIN(scr)) - width); + h = ((usableArea.y2-Y_ORIGIN(scr)) - height - extra_height); + if (w<1) w = 1; + if (h<1) h = 1; + *x_ret = X_ORIGIN(scr) + rand()%w; + *y_ret = Y_ORIGIN(scr) + rand()%h; +} + + + void PlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, unsigned width, unsigned height) { WScreen *scr = wwin->screen_ptr; int h = WMFontHeight(scr->title_font) + (wPreferences.window_title_clearance + TITLEBAR_EXTEND_SPACE) * 2; - + WArea usableArea = wGetUsableAreaForHead(scr, + wGetHeadForPointerLocation(scr), + NULL); + switch (wPreferences.window_placement) { case WPM_MANUAL: InteractivePlaceWindow(wwin, x_ret, y_ret, width, height); break; case WPM_SMART: - smartPlaceWindow(wwin, x_ret, y_ret, width, height); + smartPlaceWindow(wwin, x_ret, y_ret, width, height, usableArea); break; case WPM_AUTO: - if (autoPlaceWindow(wwin, x_ret, y_ret, width, height, 0)) { + if (autoPlaceWindow(wwin, x_ret, y_ret, width, height, 0, + usableArea)) { break; - } else if (autoPlaceWindow(wwin, x_ret, y_ret, width, height, 1)) { + } else if (autoPlaceWindow(wwin, x_ret, y_ret, width, height, 1, + usableArea)) { break; } /* there isn't a break here, because if we fail, it should fall @@ -579,32 +617,17 @@ PlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, if (wPreferences.window_placement == WPM_AUTO) scr->cascade_index++; - cascadeWindow(scr, wwin, x_ret, y_ret, width, height, h); + cascadeWindow(scr, wwin, x_ret, y_ret, width, height, h, usableArea); if (wPreferences.window_placement == WPM_CASCADE) scr->cascade_index++; break; case WPM_RANDOM: - { - int w, h, extra_height; - WArea usableArea = scr->totalUsableArea; - - if (wwin->frame) - extra_height = wwin->frame->top_width + wwin->frame->bottom_width + 2; - else - extra_height = 24; /* random value */ - - w = ((usableArea.x2-X_ORIGIN(scr)) - width); - h = ((usableArea.y2-Y_ORIGIN(scr)) - height - extra_height); - if (w<1) w = 1; - if (h<1) h = 1; - *x_ret = X_ORIGIN(scr) + rand()%w; - *y_ret = Y_ORIGIN(scr) + rand()%h; - } + randomPlaceWindow(scr, wwin, x_ret, y_ret, width, height, usableArea); break; -#ifdef DEBUG +#ifdef DEBUG default: puts("Invalid window placement!!!"); *x_ret = 0; @@ -612,15 +635,20 @@ PlaceWindow(WWindow *wwin, int *x_ret, int *y_ret, #endif } - if (*x_ret + width > scr->scr_width) - *x_ret = scr->scr_width - width; - if (*x_ret < 0) - *x_ret = 0; - - if (*y_ret + height > scr->scr_height) - *y_ret = scr->scr_height - height; - if (*y_ret < 0) - *y_ret = 0; + /* + * clip to usableArea instead of full screen + * this will also take dock/clip etc.. into account + * aswell as being xinerama friendly + */ + if (*x_ret + width > usableArea.x2) + *x_ret = usableArea.x2 - width; + if (*x_ret < usableArea.x1) + *x_ret = usableArea.x1; + + if (*y_ret + height > usableArea.y2) + *y_ret = usableArea.y2 - height; + if (*y_ret < usableArea.y1) + *y_ret = usableArea.y1; } diff --git a/src/screen.c b/src/screen.c index 940449d9..9a9acebb 100644 --- a/src/screen.c +++ b/src/screen.c @@ -605,7 +605,6 @@ wScreenInit(int screen_number) RContextAttributes rattr; extern int wVisualID; long event_mask; - WMColor *color; XErrorHandler oldHandler; scr = wmalloc(sizeof(WScreen)); @@ -666,10 +665,7 @@ wScreenInit(int screen_number) return NULL; } -#ifdef XINERAMA wInitXinerama(scr); -#endif - XDefineCursor(dpy, scr->root_win, wCursor[WCUR_ROOT]); @@ -832,19 +828,9 @@ wScreenInit(int screen_number) -static WArea subtractRectangle(WArea area, WArea rect) -{ - WArea result = area; - - -} - - void wScreenUpdateUsableArea(WScreen *scr) { - WReservedArea *area; - scr->totalUsableArea = scr->usableArea; @@ -1119,7 +1105,46 @@ wScreenBringInside(WScreen *scr, int *x, int *y, int width, int height) { int moved = 0; int tol_w, tol_h; - + /* + * With respect to the head that contains most of the window. + */ + int sx1, sy1, sx2, sy2; + + WMRect rect; + int head, flags; + + rect.pos.x = *x; + rect.pos.y = *y; + rect.size.width = width; + rect.size.height = height; + + head = wGetRectPlacementInfo(scr, rect, &flags); + rect = wGetRectForHead(scr, head); + + sx1 = rect.pos.x; + sy1 = rect.pos.y; + sx2 = sx1 + rect.size.width; + sy2 = sy1 + rect.size.height; + +#if 0 /* NOTE: gives funky group movement */ + if (flags & XFLAG_MULTIPLE) { + /* + * since we span multiple heads, pull window totaly inside + */ + if (*x < sx1) + *x = sx1, moved = 1; + else if (*x + width > sx2) + *x = sx2 - width, moved = 1; + + if (*y < sy1) + *y = sy1, moved = 1; + else if (*y + height > sy2) + *y = sy2 - height, moved = 1; + + return moved; + } +#endif + if (width > 20) tol_w = width/2; else @@ -1130,15 +1155,51 @@ wScreenBringInside(WScreen *scr, int *x, int *y, int width, int height) else tol_h = 20; - if (*x+width < 10) - *x = -tol_w, moved = 1; - else if (*x >= scr->scr_width - 10) - *x = scr->scr_width - tol_w - 1, moved = 1; + if (*x + width < sx1 + 10) + *x = sx1 - tol_w, moved = 1; + else if (*x >= sx2 - 10) + *x = sx2 - tol_w - 1, moved = 1; + + if (*y < sy1 - height + 10) + *y = sy1 - tol_h, moved = 1; + else if (*y >= sy2 - 10) + *y = sy2 - tol_h - 1, moved = 1; + + return moved; +} + + - if (*y < -height + 10) - *y = -tol_h, moved = 1; - else if (*y >= scr->scr_height - 10) - *y = scr->scr_height - tol_h - 1, moved = 1; +int +wScreenKeepInside(WScreen *scr, int *x, int *y, int width, int height) +{ + int moved = 0; + int sx1, sy1, sx2, sy2; + WMRect rect; + int head; + + rect.pos.x = *x; + rect.pos.y = *y; + rect.size.width = width; + rect.size.height = height; + + head = wGetHeadForRect(scr, rect); + rect = wGetRectForHead(scr, head); + + sx1 = rect.pos.x; + sy1 = rect.pos.y; + sx2 = sx1 + rect.size.width; + sy2 = sy1 + rect.size.height; + + if (*x < sx1) + *x = sx1, moved = 1; + else if (*x + width > sx2) + *x = sx2 - width, moved = 1; + + if (*y < sy1) + *y = sy1, moved = 1; + else if (*y + height > sy2) + *y = sy2 - height, moved = 1; return moved; } diff --git a/src/screen.h b/src/screen.h index bc5129a3..292da8fb 100644 --- a/src/screen.h +++ b/src/screen.h @@ -95,9 +95,9 @@ typedef struct _WScreen { #ifdef XINERAMA XineramaScreenInfo *xine_screens; +#endif int xine_count; /* 0 means not active */ int xine_primary_head; /* main working screen */ -#endif Window no_focus_win; /* window to get focus when nobody * else can do it */ @@ -348,6 +348,8 @@ void wScreenSaveState(WScreen *scr); void wScreenRestoreState(WScreen *scr); int wScreenBringInside(WScreen *scr, int *x, int *y, int width, int height); +int wScreenKeepInside(WScreen *scr, int *x, int *y, int width, int height); + /* in startup.c */ WScreen *wScreenWithNumber(int i); diff --git a/src/window.c b/src/window.c index ed49de7d..58c3715b 100644 --- a/src/window.c +++ b/src/window.c @@ -53,6 +53,7 @@ #include "stacking.h" #include "defaults.h" #include "workspace.h" +#include "xinerama.h" #ifdef MWM_HINTS @@ -774,6 +775,8 @@ wManageWindow(WScreen *scr, Window window) /* get geometry stuff */ wClientGetNormalHints(wwin, &wattribs, True, &x, &y, &width, &height); +/* printf( "wManageWindow: %d %d %d %d\n", x, y, width, height);*/ + /* get colormap windows */ GetColormapWindows(wwin); @@ -1099,27 +1102,114 @@ wManageWindow(WScreen *scr, Window window) if (transientOwner && transientOwner->flags.mapped) { int offs = WMAX(20, 2*transientOwner->frame->top_width); + WMRect rect; + int head; x = transientOwner->frame_x + abs((transientOwner->frame->core->width - width)/2) + offs; y = transientOwner->frame_y + abs((transientOwner->frame->core->height - height)/3) + offs; - if (x < 0) - x = 0; - else if (x + width > scr->scr_width) - x = scr->scr_width - width; + /* + * limit transient windows to be inside their parent's head + */ + rect.pos.x = transientOwner->frame_x; + rect.pos.y = transientOwner->frame_y; + rect.size.width = transientOwner->frame->core->width; + rect.size.height = transientOwner->frame->core->height; + + head = wGetHeadForRect(scr, rect); + rect = wGetRectForHead(scr, head); + + if (x < rect.pos.x) + x = rect.pos.x; + else if (x + width > rect.pos.x + rect.size.width) + x = rect.pos.x + rect.size.width - width; + + if (y < rect.pos.y) + y = rect.pos.y; + else if (y + height > rect.pos.y + rect.size.height) + y = rect.pos.y + rect.size.height - height; - if (y < 0) - y = 0; - else if (y + height > scr->scr_height) - y = scr->scr_height - height; } else { PlaceWindow(wwin, &x, &y, width, height); } if (wPreferences.window_placement == WPM_MANUAL) dontBring = True; } + else if (scr->xine_count && + wwin->normal_hints->flags & PPosition) { + int head, flags; + WMRect rect; + int reposition = 0; + + /* + * Make spash screens come out in the center of a head + * trouble is that most splashies never get here + * they are managed trough atoms but god knows where. + * Dan, do you know ? + * + * Most of them are not managed, they are set + * OverrideRedirect, which means we can't do anything about + * them. -alfredo + */ +#if 0 + printf( "xinerama PPosition: x: %d %d\n", x, (scr->scr_width - width)/2); + printf( "xinerama PPosition: y: %d %d\n", y, (scr->scr_height - height)/2); + + if ( (unsigned)(x + (width - scr->scr_width)/2 + 10) < 20 && + (unsigned)(y + (height - scr->scr_height)/2 + 10) < 20) { + + reposition = 1; + + } else +#endif + { + /* + * xinerama checks for: across head and dead space + */ + rect.pos.x = x; + rect.pos.y = y; + rect.size.width = width; + rect.size.height = height; + + head = wGetRectPlacementInfo(scr, rect, &flags); + + if (flags & XFLAG_DEAD) + reposition = 1; + + if (flags & XFLAG_MULTIPLE) + reposition = 2; + } + + switch (reposition) { + case 1: + head = wGetHeadForPointerLocation(scr); + rect = wGetRectForHead(scr, head); + + x = rect.pos.x + (x * rect.size.width)/scr->scr_width; + y = rect.pos.y + (y * rect.size.height)/scr->scr_height; + break; + + case 2: + rect = wGetRectForHead(scr, head); + + if (x < rect.pos.x) + x = rect.pos.x; + else if (x + width > rect.pos.x + rect.size.width) + x = rect.pos.x + rect.size.width - width; + + if (y < rect.pos.y) + y = rect.pos.y; + else if (y + height > rect.pos.y + rect.size.height) + y = rect.pos.y + rect.size.height - height; + + break; + + default: + break; + } + } if (WFLAGP(wwin, dont_move_off) && dontBring) wScreenBringInside(scr, &x, &y, width, height); diff --git a/src/xinerama.c b/src/xinerama.c index 92d5330d..c6e6f5c3 100644 --- a/src/xinerama.c +++ b/src/xinerama.c @@ -23,92 +23,91 @@ #include "wconfig.h" -#ifdef XINERAMA - - #include "xinerama.h" #include "screen.h" #include "window.h" #include "framewin.h" #include "wcore.h" +#include "funcs.h" +#ifdef XINERAMA #include - +#endif void wInitXinerama(WScreen *scr) { + scr->xine_screens = 0; + scr->xine_count = 0; +#ifdef XINERAMA scr->xine_screens = XineramaQueryScreens(dpy, &scr->xine_count); - +#endif scr->xine_primary_head = 0; } -/* - * intersect_rectangles- - * Calculate the rectangle that results from the intersection of - * 2 rectangles. - * - * Returns: - * 0 if the rectangles do not intersect, 1 otherwise. - */ - -typedef struct { - int x1, y1, x2, y2; -} _Rectangle; - -int intersect_rectangles(_Rectangle *rect1, - _Rectangle *rect2, - _Rectangle *result) +int wGetRectPlacementInfo(WScreen *scr, WMRect rect, int *flags) { - if (rect1->x1 < rect2->x1) - result->x1 = rect2->x1; - else - result->x1 = rect1->x1; - - if (rect1->x2 > rect2->x2) - result->x2 = rect2->x2; - else - result->x2 = rect1->x2; - - if (rect1->y1 < rect2->y1) - result->y1 = rect2->y1; - else - result->y1 = rect1->y1; - - if (rect1->y2 > rect2->y2) - result->y2 = rect2->y2; - else - result->y2 = rect1->y2; + int best; + unsigned long area, totalArea; + int i; + int rx = rect.pos.x; + int ry = rect.pos.y; + int rw = rect.size.width; + int rh = rect.size.height; + + wassertrv(flags!=NULL, 0); - if (result->x2 < result->x1) - return 0; - if (result->y2 < result->y1) - return 0; + best = -1; + area = 0; + totalArea = 0; - return 1; -} + *flags = XFLAG_NONE; -static int intersectArea(int x1, int y1, int w1, int h1, - int x2, int y2, int w2, int h2) -{ - _Rectangle rect1, rect2, result; - - rect1.x1 = x1; - rect1.y1 = y1; - rect1.x2 = x1+w1; - rect1.y2 = y1+h1; - - rect2.x1 = x2; - rect2.y1 = y2; - rect2.x2 = x2+w2; - rect2.y2 = y2+h2; - - if (intersect_rectangles(&rect1, &rect2, &result)) - return (result.x2-result.x1)*(result.y2-result.y1); - else - return 0; + if (scr->xine_count <= 1) { + unsigned long a; + + a = calcIntersectionArea(rx, ry, rw, rh, + 0, 0, scr->scr_width, scr->scr_height); + + if (a == 0) { + *flags |= XFLAG_DEAD; + } else if (a != rw*rh) { + *flags |= XFLAG_PARTIAL; + } + + return scr->xine_primary_head; + } + +#ifdef XINERAMA + for (i = 0; i < scr->xine_count; i++) { + unsigned long a; + + a = calcIntersectionArea(rx, ry, rw, rh, + scr->xine_screens[i].x_org, + scr->xine_screens[i].y_org, + scr->xine_screens[i].width, + scr->xine_screens[i].height); + + totalArea += a; + if (a > area) { + if ( best != -1) + *flags |= XFLAG_MULTIPLE; + area = a; + best = i; + } + } + + if ( best == -1) { + *flags |= XFLAG_DEAD; + best = wGetHeadForPointerLocation(scr); + } else if ( totalArea != rw*rh) + *flags |= XFLAG_PARTIAL; + + return best; +#endif } + /* get the head that covers most of the rectangle */ @@ -122,17 +121,21 @@ int wGetHeadForRect(WScreen *scr, WMRect rect) int rw = rect.size.width; int rh = rect.size.height; + if (!scr->xine_count) + return scr->xine_primary_head; + best = -1; area = 0; +#ifdef XINERAMA for (i = 0; i < scr->xine_count; i++) { unsigned long a; - a = intersectArea(rx, ry, rw, rh, - scr->xine_screens[i].x_org, - scr->xine_screens[i].y_org, - scr->xine_screens[i].width, - scr->xine_screens[i].height); + a = calcIntersectionArea(rx, ry, rw, rh, + scr->xine_screens[i].x_org, + scr->xine_screens[i].y_org, + scr->xine_screens[i].width, + scr->xine_screens[i].height); if (a > area) { area = a; @@ -140,7 +143,16 @@ int wGetHeadForRect(WScreen *scr, WMRect rect) } } + /* + * in case rect is in dead space, return valid head + */ + if (best == -1) + best = wGetHeadForPointerLocation(scr); + return best; +#else /* !XINERAMA */ + return scr->xine_primary_head; +#endif /* !XINERAMA */ } @@ -157,11 +169,20 @@ int wGetHeadForWindow(WWindow *wwin) } -int wGetHeadForPoint(WScreen *scr, WMPoint point) +/* +int wGetHeadForPoint(WScreen *scr, WMPoint point, int *flags) { int i; + // paranoia + if ( flags == NULL) { + static int tmp; + flags = &tmp; + } + *flags = XFLAG_NONE; + for (i = 0; i < scr->xine_count; i++) { +#if 0 int yy, xx; xx = scr->xine_screens[i].x_org + scr->xine_screens[i].width; @@ -171,10 +192,38 @@ int wGetHeadForPoint(WScreen *scr, WMPoint point) point.x < xx && point.y < yy) { return i; } +#else + XineramaScreenInfo *xsi = &scr->xine_screens[i]; + + if ((unsigned)(point.x - xsi->x_org) < xsi->width && + (unsigned)(point.y - xsi->y_org) < xsi->height) + return i; +#endif } + + *flags |= XFLAG_DEAD; return scr->xine_primary_head; } +*/ + + + +int wGetHeadForPoint(WScreen *scr, WMPoint point) +{ +#ifdef XINERAMA + int i; + + for (i = 0; i < scr->xine_count; i++) { + XineramaScreenInfo *xsi = &scr->xine_screens[i]; + + if ((unsigned)(point.x - xsi->x_org) < xsi->width && + (unsigned)(point.y - xsi->y_org) < xsi->height) + return i; + } +#endif /* XINERAMA */ + return scr->xine_primary_head; +} int wGetHeadForPointerLocation(WScreen *scr) @@ -184,6 +233,8 @@ int wGetHeadForPointerLocation(WScreen *scr) int ble; unsigned int blo; + if (!scr->xine_count) + return scr->xine_primary_head; if (!XQueryPointer(dpy, scr->root_win, &bla, &bla, &point.x, &point.y, @@ -200,12 +251,15 @@ wGetRectForHead(WScreen *scr, int head) { WMRect rect; +#ifdef XINERAMA if (head < scr->xine_count) { rect.pos.x = scr->xine_screens[head].x_org; rect.pos.y = scr->xine_screens[head].y_org; rect.size.width = scr->xine_screens[head].width; rect.size.height = scr->xine_screens[head].height; - } else { + } else +#endif /* XINERAMA */ + { rect.pos.x = 0; rect.pos.y = 0; rect.size.width = scr->scr_width; @@ -216,24 +270,36 @@ wGetRectForHead(WScreen *scr, int head) } -WMRect -wGetUsableRectForHead(WScreen *scr, int head) + +WArea wGetUsableAreaForHead(WScreen *scr, int head, WArea *totalAreaPtr) { - WMRect rect; + WArea totalArea, usableArea = scr->totalUsableArea; + WMRect rect = wGetRectForHead(scr, head); - if (head < scr->xine_count) { - rect.pos.x = scr->xine_screens[head].x_org; - rect.pos.y = scr->xine_screens[head].y_org; - rect.size.width = scr->xine_screens[head].width; - rect.size.height = scr->xine_screens[head].height; - } else { - rect.pos.x = 0; - rect.pos.y = 0; - rect.size.width = scr->scr_width; - rect.size.height = scr->scr_height; - } + totalArea.x1 = rect.pos.x; + totalArea.y1 = rect.pos.y; + totalArea.x2 = totalArea.x1 + rect.size.width; + totalArea.y2 = totalArea.y1 + rect.size.height; - return rect; + if (totalAreaPtr != NULL) *totalAreaPtr = totalArea; + + usableArea.x1 = WMAX(totalArea.x1, usableArea.x1); + usableArea.y1 = WMAX(totalArea.y1, usableArea.y1); + usableArea.x2 = WMIN(totalArea.x2, usableArea.x2); + usableArea.y2 = WMIN(totalArea.y2, usableArea.y2); + + return usableArea; +} + + +WMPoint wGetPointToCenterRectInHead(WScreen *scr, int head, int width, int height) +{ + WMPoint p; + WMRect rect = wGetRectForHead(scr, head); + + p.x = rect.pos.x + (rect.size.width - width)/2; + p.y = rect.pos.y + (rect.size.height - height)/2; + + return p; } -#endif diff --git a/src/xinerama.h b/src/xinerama.h index b8f15ecd..50f21cad 100644 --- a/src/xinerama.h +++ b/src/xinerama.h @@ -29,6 +29,14 @@ void wInitXinerama(WScreen *scr); + +#define XFLAG_NONE 0x00 +#define XFLAG_DEAD 0x01 +#define XFLAG_MULTIPLE 0x02 +#define XFLAG_PARTIAL 0x04 + +int wGetRectPlacementInfo(WScreen *scr, WMRect rect, int *flags); + int wGetHeadForRect(WScreen *scr, WMRect rect); int wGetHeadForWindow(WWindow *wwin); @@ -39,7 +47,9 @@ int wGetHeadForPointerLocation(WScreen *scr); WMRect wGetRectForHead(WScreen *scr, int head); -WMRect wGetUsableRectForHead(WScreen *scr, int head); +WArea wGetUsableAreaForHead(WScreen *scr, int head, WArea *totalAreaPtr); + +WMPoint wGetPointToCenterRectInHead(WScreen *scr, int head, int width, int height); #endif diff --git a/util/wmsetbg.c b/util/wmsetbg.c index 74423e0f..7e0ad594 100644 --- a/util/wmsetbg.c +++ b/util/wmsetbg.c @@ -40,6 +40,10 @@ #include "../src/config.h" +#ifdef XINERAMA +#include +#endif + #ifdef HAVE_DLFCN_H #include #endif @@ -62,7 +66,12 @@ Window root; int scr; int scrWidth; int scrHeight; +int scrX, scrY; +#ifdef XINERAMA +XineramaScreenInfo *xine_screens; +int xine_count; +#endif Bool smooth = False; @@ -116,6 +125,86 @@ loadImage(RContext *rc, char *file) } +void applyImage( RContext * rc, BackgroundTexture *texture, RImage *image, char type, int x, int y, int width, int height) { + + int w, h; + Bool fimage = False; + + switch( toupper(type)) { + case 'S': + case 'M': + if ( type == 'S') { + w = width; + h = height; + } else { + if ( image->width*height > image->height*width) { + w = width; + h = (width*image->height) / image->width; + } else { + w = (height*image->width) / image->height; + h = height; + } + } + + if ( w != image->width || h != image->height) { + RImage * simage; + + if ( smooth) { + simage = RSmoothScaleImage( image, w, h); + } else { + simage = RScaleImage( image, w, h); + } + + if ( !simage) { + wwarning( "could not scale image:%s", RMessageForError(RErrorCode)); + return; + } + fimage = True; + image = simage; + } + + /* fall through */ + case 'C': + { + Pixmap pixmap; + + if ( !RConvertImage(rc, image, &pixmap)) { + wwarning( "could not convert texture:%s", RMessageForError(RErrorCode)); + return; + } + + if ( image->width != width || image->height != height) { + int sx, sy, w, h; + + if ( image->height < height) { + h = image->height; + y += (height - h) / 2; + sy = 0; + } else { + sy = (image->height - height) / 2; + h = height; + } + if ( image->width < width) { + w = image->width; + x += (width - w) / 2; + sx = 0; + } else { + sx = (image->width - width) / 2; + w = width; + } + + XCopyArea(dpy, pixmap, texture->pixmap, DefaultGC(dpy, scr), sx, sy, w, h, x, y); + } else + XCopyArea(dpy, pixmap, texture->pixmap, DefaultGC(dpy, scr), 0, 0, width, height, x, y); + + XFreePixmap(dpy, pixmap); + if ( fimage) RReleaseImage( image); + } + break; + } +} + + BackgroundTexture* parseTexture(RContext *rc, char *text) { @@ -404,6 +493,7 @@ parseTexture(RContext *rc, char *text) break; case 'S': case 'M': +#if 0 if (toupper(type[0])=='S') { w = scrWidth; h = scrHeight; @@ -488,10 +578,37 @@ parseTexture(RContext *rc, char *text) texture->height = scrHeight; } break; +#else + case 'C': + { + Pixmap tpixmap = XCreatePixmap( dpy, root, scrWidth, scrHeight, DefaultDepth(dpy, scr)); + XFillRectangle(dpy, tpixmap, DefaultGC(dpy, scr), 0, 0, scrWidth, scrHeight); + + texture->pixmap = tpixmap; + texture->color = color; + texture->width = scrWidth; + texture->height = scrHeight; + + if ( xine_count) { + int i; + for ( i=0; ipixmap = pixmap; texture->color = color; +#endif } else if (strcasecmp(type, "thgradient")==0 || strcasecmp(type, "tvgradient")==0 || strcasecmp(type, "tdgradient")==0) { @@ -1414,6 +1531,12 @@ main(int argc, char **argv) scrWidth = WidthOfScreen(DefaultScreenOfDisplay(dpy)); scrHeight = HeightOfScreen(DefaultScreenOfDisplay(dpy)); + scrX = scrY = 0; + +#ifdef XINERAMA + xine_screens = XineramaQueryScreens(dpy, &xine_count); +#endif + if (!obey_user && DefaultDepth(dpy, scr) <= 8) render_mode = RDitheredRendering; -- 2.11.4.GIT