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:
@@ -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
27
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.
|
||||
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?
|
||||
|
||||
@@ -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);
|
||||
|
||||
10
configure.ac
10
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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
25
src/dialog.c
25
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);
|
||||
|
||||
101
src/dock.c
101
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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
43
src/event.c
43
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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
159
src/menu.c
159
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) 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);
|
||||
|
||||
120
src/moveres.c
120
src/moveres.c
@@ -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;
|
||||
|
||||
122
src/placement.c
122
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;
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
105
src/screen.c
105
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 < -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
106
src/window.c
106
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);
|
||||
|
||||
244
src/xinerama.c
244
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 <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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
123
util/wmsetbg.c
123
util/wmsetbg.c
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user