mirror of
https://github.com/gnustep/libs-back.git
synced 2025-02-23 11:51:27 +00:00
Update window frame handling to match -gui. Improve window resizing behavior in x11 backends.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@19854 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
1d40f7d8cc
commit
0d356e9733
5 changed files with 91 additions and 198 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
2004-08-09 14:38 Alexander Malmberg <alexander@malmberg.org>
|
||||
|
||||
* Source/win32/WIN32Server.m, Source/win32/WIN32ServerEvent.m,
|
||||
Headers/win32/WIN32Geometry.h (MSScreenRectToGS, GSScreenRectToMS):
|
||||
The 'GS' rect is, in the terminology of NSWindow.h, the window frame,
|
||||
not the screen frame. make the conversions match this and update
|
||||
the callers.
|
||||
* Source/x11/XGServerWindow.m (-_OSFrameToXFrame:for:,
|
||||
-_OSFrameToXHints:for:, -_XFrameToOSFrame:for:): Update conversions.
|
||||
(-windowdevice:): Remove artificial delays and geometry querying.
|
||||
Update based on the frame from the last ConfigureNotify.
|
||||
(-placewindow::): Remove event coordinate adjustments. Always send
|
||||
move/resize events to -gui right away.
|
||||
|
||||
2004-08-03 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Header/cairo/*:
|
||||
|
|
|
@ -141,16 +141,24 @@ NSPoint MSScreenPointToGS(int x, int y)
|
|||
}
|
||||
|
||||
static inline
|
||||
NSRect MSScreenRectToGS(RECT r)
|
||||
NSRect MSScreenRectToGS(RECT r, unsigned int styleMask, WIN32Server *self)
|
||||
{
|
||||
NSRect r1;
|
||||
int screen_height = GetSystemMetrics(SM_CYSCREEN);
|
||||
float t, b, l, rr;
|
||||
|
||||
[self styleoffsets: &l : &rr : &t : &b : styleMask];
|
||||
|
||||
r1.origin.x = r.left;
|
||||
r1.origin.y = screen_height - r.bottom;
|
||||
r1.size.width = r.right - r.left;
|
||||
r1.size.height = r.bottom - r.top;
|
||||
|
||||
r1.origin.x += l;
|
||||
r1.origin.y += b;
|
||||
r1.size.width -= l + rr;
|
||||
r1.size.height -= t + b;
|
||||
|
||||
return r1;
|
||||
}
|
||||
|
||||
|
@ -166,10 +174,18 @@ POINT GSScreenPointToMS(NSPoint p)
|
|||
}
|
||||
|
||||
static inline
|
||||
RECT GSScreenRectToMS(NSRect r)
|
||||
RECT GSScreenRectToMS(NSRect r, unsigned int styleMask, WIN32Server *self)
|
||||
{
|
||||
RECT r1;
|
||||
int screen_height = GetSystemMetrics(SM_CYSCREEN);
|
||||
float t, b, l, rr;
|
||||
|
||||
[self styleoffsets: &l : &rr : &t : &b : styleMask];
|
||||
|
||||
r.origin.x -= l;
|
||||
r.origin.y -= b;
|
||||
r.size.width += l + rr;
|
||||
r.size.height += t + b;
|
||||
|
||||
r1.left = r.origin.x;
|
||||
r1.bottom = screen_height - r.origin.y;
|
||||
|
|
|
@ -302,7 +302,7 @@ DWORD windowStyleForGSStyle(unsigned int style)
|
|||
RECT r;
|
||||
DWORD wstyle = windowStyleForGSStyle(style);
|
||||
|
||||
r = GSScreenRectToMS(frame);
|
||||
r = GSScreenRectToMS(frame, style, self);
|
||||
|
||||
NSDebugLLog(@"WTrace", @"window: %@ : %d : %d : %d", NSStringFromRect(frame),
|
||||
type, style, screen);
|
||||
|
@ -487,10 +487,11 @@ DWORD windowStyleForGSStyle(unsigned int style)
|
|||
RECT r;
|
||||
RECT r2;
|
||||
WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA);
|
||||
NSWindow *window = GSWindowWithNumber(winNum);
|
||||
|
||||
NSDebugLLog(@"WTrace", @"placewindow: %@ : %d", NSStringFromRect(frame),
|
||||
winNum);
|
||||
r = GSScreenRectToMS(frame);
|
||||
r = GSScreenRectToMS(frame, [window styleMask], self);
|
||||
GetWindowRect((HWND)winNum, &r2);
|
||||
|
||||
SetWindowPos((HWND)winNum, NULL, r.left, r.top, r.right - r.left, r.bottom - r.top,
|
||||
|
@ -531,9 +532,10 @@ DWORD windowStyleForGSStyle(unsigned int style)
|
|||
- (NSRect) windowbounds: (int) winNum
|
||||
{
|
||||
RECT r;
|
||||
NSWindow *window = GSWindowWithNumber((int)hwnd);
|
||||
|
||||
GetWindowRect((HWND)winNum, &r);
|
||||
return MSScreenRectToGS(r);
|
||||
return MSScreenRectToGS(r, [window styleMask], self);
|
||||
}
|
||||
|
||||
- (void) setwindowlevel: (int) level : (int) winNum
|
||||
|
|
|
@ -181,12 +181,12 @@ static void invalidateWindow(HWND hwnd, RECT rect);
|
|||
NSRect rect;
|
||||
RECT r;
|
||||
NSEvent *ev = nil;
|
||||
NSWindow *window = GSWindowWithNumber((int)hwnd);
|
||||
|
||||
GetWindowRect(hwnd, &r);
|
||||
rect = MSScreenRectToGS(r);
|
||||
rect = MSScreenRectToGS(r, [window styleMask], self);
|
||||
eventLocation = rect.origin;
|
||||
|
||||
NSWindow *window = GSWindowWithNumber((int)hwnd);
|
||||
if (window)
|
||||
{
|
||||
if( subtype == GSAppKitWindowMoved )
|
||||
|
|
|
@ -378,14 +378,9 @@ static void setWindowHintsForStyle (Display *dpy, Window window,
|
|||
{
|
||||
gswindow_device_t *win = (gswindow_device_t*)window;
|
||||
NSRect x;
|
||||
float t, b, l, r;
|
||||
|
||||
[self styleoffsets: &l : &r : &t : &b : win->win_attrs.window_style];
|
||||
|
||||
x.size.width = o.size.width - l - r;
|
||||
x.size.height = o.size.height - t - b;
|
||||
x.origin.x = o.origin.x + l;
|
||||
x.origin.y = o.origin.y + o.size.height - t;
|
||||
x = o;
|
||||
x.origin.y = x.origin.y + o.size.height;
|
||||
x.origin.y = DisplayHeight(dpy, win->screen) - x.origin.y;
|
||||
NSDebugLLog(@"Frame", @"O2X %d, %@, %@", win->number,
|
||||
NSStringFromRect(o), NSStringFromRect(x));
|
||||
|
@ -404,11 +399,11 @@ NSDebugLLog(@"Frame", @"O2X %d, %@, %@", win->number,
|
|||
|
||||
[self styleoffsets: &l : &r : &t : &b : win->win_attrs.window_style];
|
||||
|
||||
x.size.width = o.size.width - l - r;
|
||||
x.size.height = o.size.height - t - b;
|
||||
x.origin.x = o.origin.x;
|
||||
x.size.width = o.size.width;
|
||||
x.size.height = o.size.height;
|
||||
x.origin.x = o.origin.x - l;
|
||||
x.origin.y = o.origin.y + o.size.height;
|
||||
x.origin.y = DisplayHeight(dpy, win->screen) - x.origin.y;
|
||||
x.origin.y = DisplayHeight(dpy, win->screen) - x.origin.y - t;
|
||||
NSDebugLLog(@"Frame", @"O2H %d, %@, %@", win->number,
|
||||
NSStringFromRect(o), NSStringFromRect(x));
|
||||
return x;
|
||||
|
@ -440,14 +435,10 @@ NSDebugLLog(@"Frame", @"O2H %d, %@, %@", win->number,
|
|||
{
|
||||
gswindow_device_t *win = (gswindow_device_t*)window;
|
||||
NSRect o;
|
||||
float t, b, l, r;
|
||||
|
||||
[self styleoffsets: &l : &r : &t : &b : win->win_attrs.window_style];
|
||||
o.size.width = x.size.width + l + r;
|
||||
o.size.height = x.size.height + t + b;
|
||||
o.origin.x = x.origin.x - l;
|
||||
o.origin.y = DisplayHeight(dpy, win->screen) - x.origin.y;
|
||||
o.origin.y = o.origin.y - o.size.height + t;
|
||||
o = x;
|
||||
o.origin.y = DisplayHeight(dpy, win->screen) - o.origin.y;
|
||||
o.origin.y = o.origin.y - o.size.height;
|
||||
NSDebugLLog(@"Frame", @"X2O %d, %@, %@", win->number,
|
||||
NSStringFromRect(x), NSStringFromRect(o));
|
||||
return o;
|
||||
|
@ -1423,11 +1414,7 @@ NSDebugLLog(@"Frame", @"X2O %d, %@, %@", win->number,
|
|||
*/
|
||||
- (void) windowdevice: (int)win
|
||||
{
|
||||
int x, y;
|
||||
unsigned width, height;
|
||||
unsigned old_width;
|
||||
unsigned old_height;
|
||||
XWindowAttributes winattr;
|
||||
gswindow_device_t *window;
|
||||
NSGraphicsContext *ctxt;
|
||||
|
||||
|
@ -1442,41 +1429,8 @@ NSDebugLLog(@"Frame", @"X2O %d, %@, %@", win->number,
|
|||
if (!window->ident)
|
||||
return;
|
||||
|
||||
old_width = NSWidth(window->xframe);
|
||||
old_height = NSHeight(window->xframe);
|
||||
|
||||
XFlush (dpy);
|
||||
|
||||
XGetGeometry(dpy, window->ident, &window->root,
|
||||
&x, &y, &width, &height,
|
||||
&window->border, &window->depth);
|
||||
/* hack:
|
||||
* wait until a resize of window is finished (especially for NSMenu)
|
||||
* is there any way to wait until X finished it's stuff?
|
||||
* XSync(), XFlush() doesn't do the job!
|
||||
*/
|
||||
if (height != (unsigned int)(window->siz_hints.height))
|
||||
{
|
||||
#if HAVE_USLEEP
|
||||
usleep(1);
|
||||
#else
|
||||
for (x=0; x<10000; x++)
|
||||
;
|
||||
#endif
|
||||
XGetGeometry(dpy, window->ident, &window->root,
|
||||
&x, &y, &width, &height,
|
||||
&window->border, &window->depth);
|
||||
}
|
||||
|
||||
window->xframe.size.width = width;
|
||||
window->xframe.size.height = height;
|
||||
|
||||
XGetWindowAttributes(dpy, window->ident, &winattr);
|
||||
window->map_state = winattr.map_state;
|
||||
|
||||
NSDebugLLog (@"NSWindow", @"window geom device ((%f, %f), (%f, %f))",
|
||||
window->xframe.origin.x, window->xframe.origin.y,
|
||||
window->xframe.size.width, window->xframe.size.height);
|
||||
width = NSWidth(window->xframe);
|
||||
height = NSHeight(window->xframe);
|
||||
|
||||
if (window->buffer
|
||||
&& (window->buffer_width != width || window->buffer_height != height)
|
||||
|
@ -1601,7 +1555,7 @@ static BOOL didCreatePixmaps;
|
|||
/*
|
||||
* Some window managers ignore any hints and properties until the
|
||||
* window is actually mapped, so we need to set them all up
|
||||
* immediately bofore mapping the window ...
|
||||
* immediately before mapping the window ...
|
||||
*/
|
||||
|
||||
setNormalHints(dpy, window);
|
||||
|
@ -1858,20 +1812,13 @@ static BOOL didCreatePixmaps;
|
|||
|
||||
- (void) placewindow: (NSRect)rect : (int)win
|
||||
{
|
||||
NSAutoreleasePool *arp;
|
||||
NSRect xVal;
|
||||
NSRect last;
|
||||
NSEvent *event;
|
||||
NSDate *limit;
|
||||
NSMutableArray *tmpQueue;
|
||||
unsigned pos;
|
||||
float xdiff;
|
||||
float ydiff;
|
||||
gswindow_device_t *window;
|
||||
NSWindow *nswin;
|
||||
NSRect frame;
|
||||
BOOL resize = NO;
|
||||
BOOL move = NO;
|
||||
NSEvent *e;
|
||||
NSRect xVal;
|
||||
gswindow_device_t *window;
|
||||
NSWindow *nswin;
|
||||
NSRect frame;
|
||||
BOOL resize = NO;
|
||||
BOOL move = NO;
|
||||
|
||||
window = WINDOW_WITH_TAG(win);
|
||||
if (win == 0 || window == NULL)
|
||||
|
@ -1895,8 +1842,6 @@ static BOOL didCreatePixmaps;
|
|||
{
|
||||
move = YES;
|
||||
}
|
||||
xdiff = rect.origin.x - frame.origin.x;
|
||||
ydiff = rect.origin.y - frame.origin.y;
|
||||
|
||||
xVal = [self _OSFrameToXHints: rect for: window];
|
||||
window->siz_hints.width = (int)xVal.size.width;
|
||||
|
@ -1905,8 +1850,6 @@ static BOOL didCreatePixmaps;
|
|||
window->siz_hints.y = (int)xVal.origin.y;
|
||||
xVal = [self _OSFrameToXFrame: rect for: window];
|
||||
|
||||
last = window->xframe;
|
||||
|
||||
NSDebugLLog(@"Moving", @"Place %d - o:%@, x:%@", window->number,
|
||||
NSStringFromRect(rect), NSStringFromRect(xVal));
|
||||
XMoveResizeWindow (dpy, window->ident,
|
||||
|
@ -1914,124 +1857,42 @@ static BOOL didCreatePixmaps;
|
|||
window->siz_hints.width, window->siz_hints.height);
|
||||
setNormalHints(dpy, window);
|
||||
|
||||
/*
|
||||
* Now massage all the events currently in the queue to make sure
|
||||
* mouse locations in our window are adjusted as necessary.
|
||||
*/
|
||||
arp = [NSAutoreleasePool new];
|
||||
limit = [NSDate distantPast]; /* Don't wait for new events. */
|
||||
tmpQueue = [NSMutableArray arrayWithCapacity: 8];
|
||||
for (;;)
|
||||
/* Update xframe right away. We optimistically assume that we'll get the
|
||||
frame we asked for. If we're right, -gui can update/redraw right away,
|
||||
and we don't have to do anything when the ConfigureNotify arrives later.
|
||||
If we're wrong, the ConfigureNotify will have the exact coordinates, and
|
||||
at that point, we'll send new GSAppKitWindow* events to -gui. */
|
||||
window->xframe = xVal;
|
||||
|
||||
if (resize == YES)
|
||||
{
|
||||
NSEventType type;
|
||||
|
||||
event = DPSGetEvent(self, NSAnyEventMask, limit,
|
||||
NSEventTrackingRunLoopMode);
|
||||
if (event == nil)
|
||||
break;
|
||||
type = [event type];
|
||||
if (type == NSAppKitDefined && [event windowNumber] == win)
|
||||
{
|
||||
GSAppKitSubtype sub = [event subtype];
|
||||
|
||||
/*
|
||||
* Window movement or resize events for the window we are
|
||||
* watching are posted immediately, so they can take effect
|
||||
* before the placewindow returns.
|
||||
*/
|
||||
if (sub == GSAppKitWindowMoved || sub == GSAppKitWindowResized)
|
||||
{
|
||||
[nswin sendEvent: event];
|
||||
}
|
||||
else
|
||||
{
|
||||
[tmpQueue addObject: event];
|
||||
}
|
||||
}
|
||||
else if (type != NSPeriodic && type != NSLeftMouseDragged
|
||||
&& type != NSOtherMouseDragged && type != NSRightMouseDragged
|
||||
&& type != NSMouseMoved)
|
||||
{
|
||||
/*
|
||||
* Save any events that arrive before our window is moved - excepting
|
||||
* periodic events (which we can assume will be outdated) and mouse
|
||||
* movement events (which might flood us).
|
||||
*/
|
||||
[tmpQueue addObject: event];
|
||||
}
|
||||
if (NSEqualRects(xVal, window->xframe) == YES ||
|
||||
NSEqualRects(rect, [nswin frame]) == YES)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (NSEqualRects(last, window->xframe) == NO)
|
||||
{
|
||||
NSDebugLLog(@"Moving", @"From: %@\nWant %@\nGot %@",
|
||||
NSStringFromRect(last),
|
||||
NSStringFromRect(xVal),
|
||||
NSStringFromRect(window->xframe));
|
||||
last = window->xframe;
|
||||
}
|
||||
NSDebugLLog(@"Moving", @"Fake size %d - %@", window->number,
|
||||
NSStringFromSize(rect.size));
|
||||
e = [NSEvent otherEventWithType: NSAppKitDefined
|
||||
location: rect.origin
|
||||
modifierFlags: 0
|
||||
timestamp: 0
|
||||
windowNumber: win
|
||||
context: GSCurrentContext()
|
||||
subtype: GSAppKitWindowResized
|
||||
data1: rect.size.width
|
||||
data2: rect.size.height];
|
||||
[nswin sendEvent: e];
|
||||
}
|
||||
/*
|
||||
* If we got any events while waiting for the window movement, we
|
||||
* may need to adjust their locations to match the new window position.
|
||||
*/
|
||||
pos = [tmpQueue count];
|
||||
while (pos-- > 0)
|
||||
else if (move == YES)
|
||||
{
|
||||
event = [tmpQueue objectAtIndex: pos];
|
||||
if ([event windowNumber] == win)
|
||||
{
|
||||
NSPoint loc = [event locationInWindow];
|
||||
|
||||
loc.x -= xdiff;
|
||||
loc.y -= ydiff;
|
||||
[event _patchLocation: loc];
|
||||
}
|
||||
DPSPostEvent(self, event, YES);
|
||||
}
|
||||
RELEASE(arp);
|
||||
|
||||
/*
|
||||
* Failsafe - if X hasn't told us it has moved/resized the window, we
|
||||
* fake the notification and post them immediately, so they can take
|
||||
* effect before the placewindow returns.
|
||||
*/
|
||||
if (NSEqualRects([nswin frame], rect) == NO)
|
||||
{
|
||||
NSEvent *e;
|
||||
|
||||
if (resize == YES)
|
||||
{
|
||||
NSDebugLLog(@"Moving", @"Fake size %d - %@", window->number,
|
||||
NSStringFromSize(rect.size));
|
||||
e = [NSEvent otherEventWithType: NSAppKitDefined
|
||||
location: rect.origin
|
||||
modifierFlags: 0
|
||||
timestamp: 0
|
||||
windowNumber: win
|
||||
context: GSCurrentContext()
|
||||
subtype: GSAppKitWindowResized
|
||||
data1: rect.size.width
|
||||
data2: rect.size.height];
|
||||
[nswin sendEvent: e];
|
||||
}
|
||||
if (move == YES)
|
||||
{
|
||||
NSDebugLLog(@"Moving", @"Fake move %d - %@", window->number,
|
||||
NSStringFromPoint(rect.origin));
|
||||
e = [NSEvent otherEventWithType: NSAppKitDefined
|
||||
location: NSZeroPoint
|
||||
modifierFlags: 0
|
||||
timestamp: 0
|
||||
windowNumber: win
|
||||
context: GSCurrentContext()
|
||||
subtype: GSAppKitWindowMoved
|
||||
data1: rect.origin.x
|
||||
data2: rect.origin.y];
|
||||
[nswin sendEvent: e];
|
||||
}
|
||||
NSDebugLLog(@"Moving", @"Fake move %d - %@", window->number,
|
||||
NSStringFromPoint(rect.origin));
|
||||
e = [NSEvent otherEventWithType: NSAppKitDefined
|
||||
location: NSZeroPoint
|
||||
modifierFlags: 0
|
||||
timestamp: 0
|
||||
windowNumber: win
|
||||
context: GSCurrentContext()
|
||||
subtype: GSAppKitWindowMoved
|
||||
data1: rect.origin.x
|
||||
data2: rect.origin.y];
|
||||
[nswin sendEvent: e];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue