1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-18 20:10:29 +01:00

- Fixed sloppy focus bug (Pawel S. Veselov <pv76716@druid.SFBay.Sun.COM>)

- Applied Xinerama patch (after fixes) from (Peter Zijlstra
  <a.p.zijlstra@chello.nl>)
This commit is contained in:
kojima
2002-11-28 22:04:07 +00:00
parent 0fe70d2b4e
commit a10214a502
21 changed files with 909 additions and 403 deletions

View File

@@ -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 <davidc@debian.org>)
- Fixed bug with resizebars appearing out of nothing when reloading configs
- Fixed sloppy focus bug (Pawel S. Veselov <pv76716@druid.SFBay.Sun.COM>)
- Applied Xinerama patch (after fixes) from (Peter Zijlstra
<a.p.zijlstra@chello.nl>)
Changes since version 0.80.0:
.............................

27
FAQ
View File

@@ -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.
This question was officially answered as follows:
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.
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?

View File

@@ -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);

View File

@@ -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"

View File

@@ -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;
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;
/* 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;
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);
head = wGetHeadForRect(scr, rect);
} else
*/
head = wGetHeadForPointerLocation(scr);
rect = wGetRectForHead(scr, head);
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;

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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;
/*
* make things relative to head
*/
{
WMRect rect = wGetRectForHead(scr, wGetHeadForPointerLocation(scr));
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;
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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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) x = rect.pos.x;
if (y<rect.pos.y) y = rect.pos.y;
if (x+MENUW(menu) > 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 (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 <= 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 (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);

View File

@@ -41,6 +41,8 @@
#include "workspace.h"
#include "geomview.h"
#include "screen.h"
#include "xinerama.h"
#include <WINGs/WINGsP.h>
@@ -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;

View File

@@ -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;
/*
* 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 > scr->scr_height)
*y_ret = scr->scr_height - height;
if (*y_ret < 0)
*y_ret = 0;
if (*y_ret + height > usableArea.y2)
*y_ret = usableArea.y2 - height;
if (*y_ret < usableArea.y1)
*y_ret = usableArea.y1;
}

View File

@@ -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 < -height + 10)
*y = -tol_h, moved = 1;
else if (*y >= scr->scr_height - 10)
*y = scr->scr_height - tol_h - 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;
}
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;
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 <X11/extensions/Xinerama.h>
#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;
if (result->x2 < result->x1)
return 0;
if (result->y2 < result->y1)
return 0;
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;
return 1;
}
wassertrv(flags!=NULL, 0);
best = -1;
area = 0;
totalArea = 0;
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;
*flags = XFLAG_NONE;
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

View File

@@ -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

View File

@@ -40,6 +40,10 @@
#include "../src/config.h"
#ifdef XINERAMA
#include <X11/extensions/Xinerama.h>
#endif
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#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; i<xine_count; ++i) {
applyImage( rc, texture, image, type[0],
xine_screens[i].x_org, xine_screens[i].y_org,
xine_screens[i].width, xine_screens[i].height);
}
} else {
applyImage( rc, texture, image, type[0], 0, 0, scrWidth, scrHeight);
}
RReleaseImage( image);
}
break;
#endif
}
#if 0
texture->pixmap = 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;