Improve handling of ConfigureNotify events. Add GSX11HandlesWindowDecorations defaults and code to handle it.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@19623 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Alexander Malmberg 2004-06-26 11:09:39 +00:00
parent 6eb283e349
commit 40c4368cc9
4 changed files with 125 additions and 39 deletions

View file

@ -1,3 +1,24 @@
2004-06-26 13:04 Alexander Malmberg <alexander@malmberg.org>
* Source/x11/XGServerEvent.m (-processEvent: ConfigureNotify):
Don't ignore the event for unmapped windows. Use XTranslateCoordinates
to get the size and position right for both real and artificial
events. Only update the position hints if we're mapped.
* Source/x11/XGServerWindow.m: Add handlesWindowDecorations variable.
(-handlesWindowDecorations): New method.
(setWindowHintsForStyle, -styleoffsets:::::): If we aren't handling
window decorations, treat all windows as borderless.
(-stylewindow::, -setinputstate::): Assert that we're handling window
decorations.
(-window::::): Create the window structure earlier so it can be used
to convert frames.
(-_setupRootWindow): Set handlesWindowDecorations based on the
GSX11HandlesWindowDecorations defaults value.
* Documentation/Back/DefaultsSummary.gsdoc: Document
GSX11HandlesWindowDecorations.
2004-06-19 Fred Kiefer <FredKiefer@gmx.de>
* Source/win32/WIN32Server.m (-findWindowAt:windowRef:excluding:)

View file

@ -110,6 +110,16 @@
<code>OverTheSpot</code>.
</p>
</desc>
<term>GSX11HandlesWindowDecorations</term>
<desc>
<p> [X11-based backends only]
A boolean value, by default <code>YES</code>, which indicates if
the backend should let the window manager handle window
decorations. When set to <code>NO</code>, GNUstep-GUI will handle
the window decorations, which is particularly useful if you aren't
running any window manager.
</p>
</desc>
<term>GraphicCompositing</term>
<desc>
<p> [Xlib backend only]

View file

@ -685,34 +685,45 @@ static inline int check_modifier (XEvent *xEvent, KeyCode key_code)
xEvent.xconfigure.send_event ? 'T' : 'F');
if (cWin == 0 || xEvent.xconfigure.window != cWin->ident)
generic.cachedWindow = [XGServer _windowForXWindow:xEvent.xconfigure.window];
/*
* Ignore events for unmapped windows.
*/
if (cWin != 0 && cWin->map_state == IsViewable)
if (cWin != 0)
{
NSRect r, x, n, h;
NSTimeInterval ts = (NSTimeInterval)generic.lastMotion;
/*
* Get OpenStep frame coordinates from X frame.
* If it's not from the window mmanager, ignore x and y.
*/
r = cWin->xframe;
x = NSMakeRect(xEvent.xconfigure.x,
xEvent.xconfigure.y,
xEvent.xconfigure.width,
xEvent.xconfigure.height);
/*
According to the ICCCM, coordinates in synthetic events
(ie. non-zero send_event) are in root space, while coordinates
in real events are in the parent window's space. The parent
window might be some window manager window, so we can't
directly use those coordinates.
Thus, if the event is real, we use XTranslateCoordinates to
get the root space coordinates.
*/
if (xEvent.xconfigure.send_event == 0)
{
x = NSMakeRect(r.origin.x, r.origin.y,
xEvent.xconfigure.width, xEvent.xconfigure.height);
}
else
{
x = NSMakeRect(xEvent.xconfigure.x,
xEvent.xconfigure.y,
xEvent.xconfigure.width,
xEvent.xconfigure.height);
cWin->xframe.origin = x.origin;
int root_x, root_y;
Window root_child;
XTranslateCoordinates(dpy, xEvent.xconfigure.window,
RootWindow(dpy, cWin->screen),
0, 0,
&root_x, &root_y,
&root_child);
x.origin.x = root_x;
x.origin.y = root_y;
}
cWin->xframe = x;
n = [self _XFrameToOSFrame: x for: cWin];
NSDebugLLog(@"Moving",
NSDebugLLog(@"Moving",
@"Update win %d:\n original:%@\n new:%@",
cWin->number, NSStringFromRect(r),
NSStringFromRect(x));
@ -722,18 +733,26 @@ static inline int check_modifier (XEvent *xEvent, KeyCode key_code)
h = [self _OSFrameToXHints: n for: cWin];
cWin->siz_hints.width = h.size.width;
cWin->siz_hints.height = h.size.height;
//if (xEvent.xconfigure.send_event != 0)
{
cWin->siz_hints.x = h.origin.x;
cWin->siz_hints.y = h.origin.y;
}
/*
We only update the position hints if we're on the screen.
Otherwise, the window manager might not have added decorations
(if any) to the window yet. Since we compensate for decorations
when we set the position, this will confuse us and we'll end
up compensating twice, which makes windows drift.
*/
if (cWin->map_state == IsViewable)
{
cWin->siz_hints.x = h.origin.x;
cWin->siz_hints.y = h.origin.y;
}
/*
* create GNUstep event(s)
*/
if (!NSEqualSizes(r.size, x.size))
{
/* Resize events move the origin. There's no goo
/* Resize events move the origin. There's no good
place to pass this info back, so we put it in
the event location field */
e = [NSEvent otherEventWithType: NSAppKitDefined

View file

@ -31,6 +31,7 @@
#include <Foundation/NSUserDefaults.h>
#include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSDebug.h>
#include <Foundation/NSException.h>
#include <AppKit/DPSOperators.h>
#include <AppKit/NSApplication.h>
#include <AppKit/NSCursor.h>
@ -57,6 +58,10 @@
#define ROOT generic.appRootWindow
static BOOL handlesWindowDecorations = YES;
/*
* Name for application root window.
*/
@ -232,7 +237,8 @@ static void setWindowHintsForStyle (Display *dpy, Window window,
hints->functions = 0;
/* Now add to the hints from the styleMask */
if (styleMask == NSBorderlessWindowMask)
if (styleMask == NSBorderlessWindowMask
|| !handlesWindowDecorations)
{
hints->flags |= MWM_HINTS_DECORATIONS;
hints->flags |= MWM_HINTS_FUNCTIONS;
@ -321,6 +327,12 @@ static void setWindowHintsForStyle (Display *dpy, Window window,
@implementation XGServer (WindowOps)
-(BOOL) handlesWindowDecorations
{
return handlesWindowDecorations;
}
/*
* Where a window has been reparented by the wm, we use this method to
* locate the window given knowledge of its border window.
@ -744,6 +756,10 @@ NSDebugLLog(@"Frame", @"X2O %d, %@, %@", win->number,
* Now check user defaults.
*/
defs = [NSUserDefaults standardUserDefaults];
if ([defs objectForKey: @"GSX11HandlesWindowDecorations"])
handlesWindowDecorations = [defs boolForKey: @"GSX11HandlesWindowDecorations"];
generic.flags.useWindowMakerIcons = NO;
if ((generic.wm & XGWM_WINDOWMAKER) != 0)
{
@ -935,7 +951,20 @@ NSDebugLLog(@"Frame", @"X2O %d, %@, %@", win->number,
root = [self _rootWindowForScreen: screen];
context = [self xrContextForScreen: screen];
frame = [NSWindow contentRectForFrameRect: frame styleMask: style];
/* Create the window structure and set the style early so we can use it to
convert frames. */
window = objc_malloc(sizeof(gswindow_device_t));
memset(window, '\0', sizeof(gswindow_device_t));
window->display = dpy;
window->screen = screen;
window->win_attrs.flags |= GSWindowStyleAttr;
if (handlesWindowDecorations)
window->win_attrs.window_style = style;
else
window->win_attrs.window_style = style & (NSIconWindowMask | NSMiniWindowMask);
frame = [self _OSFrameToXFrame: frame for: window];
/* We're not allowed to create a zero rect window */
if (NSWidth(frame) <= 0 || NSHeight(frame) <= 0)
@ -943,13 +972,6 @@ NSDebugLLog(@"Frame", @"X2O %d, %@, %@", win->number,
frame.size.width = 2;
frame.size.height = 2;
}
/* Translate to X coordinates */
frame.origin.y = DisplayHeight(dpy, screen) - NSMaxY(frame);
window = objc_malloc(sizeof(gswindow_device_t));
memset(window, '\0', sizeof(gswindow_device_t));
window->display = dpy;
window->screen = screen;
window->xframe = frame;
window->type = type;
window->root = root->ident;
@ -966,7 +988,7 @@ NSDebugLLog(@"Frame", @"X2O %d, %@, %@", win->number,
context->depth,
CopyFromParent,
context->visual,
(CWColormap | CWBackPixel|CWBorderPixel),
(CWColormap | CWBackPixel | CWBorderPixel),
&window->xwn_attrs);
/*
@ -1002,15 +1024,13 @@ NSDebugLLog(@"Frame", @"X2O %d, %@, %@", win->number,
* Initial attributes for any GNUstep window tell Window Maker not to
* create an app icon for us.
*/
window->win_attrs.flags = GSExtraFlagsAttr;
window->win_attrs.extra_flags = GSNoApplicationIconFlag;
window->win_attrs.flags |= GSExtraFlagsAttr;
window->win_attrs.extra_flags |= GSNoApplicationIconFlag;
/*
* Prepare size/position hints, but don't set them now - ordering
* the window in should automatically do it.
*/
window->win_attrs.flags |= GSWindowStyleAttr;
window->win_attrs.window_style = style;
frame = [self _XFrameToOSFrame: window->xframe for: window];
frame = [self _OSFrameToXHints: frame for: window];
window->siz_hints.x = NSMinX(frame);
@ -1125,6 +1145,17 @@ NSDebugLLog(@"Frame", @"X2O %d, %@, %@", win->number,
- (void) styleoffsets: (float *) l : (float *) r : (float *) t : (float *) b
: (unsigned int) style
{
if (!handlesWindowDecorations)
{
/*
If we don't handle decorations, all our windows are going to be
border- and decorationless. In that case, -gui won't call this method,
but we still use it internally.
*/
*l = *r = *t = *b = 0.0;
return;
}
/* First try to get the offset information that we have obtained from
the WM. This will only work if the application has already created
a window that has been reparented by the WM. Otherwise we have to
@ -1212,6 +1243,8 @@ NSDebugLLog(@"Frame", @"X2O %d, %@, %@", win->number,
{
gswindow_device_t *window;
NSAssert(handlesWindowDecorations, @"-stylewindow:: called when handlesWindowDecorations==NO");
window = WINDOW_WITH_TAG(win);
if (!window)
return;
@ -2369,6 +2402,9 @@ NSDebugLLog(@"Frame", @"X2O %d, %@, %@", win->number,
*/
- (void) setinputstate: (int)st : (int)win
{
if (!handlesWindowDecorations)
return;
NSDebugLLog(@"XGTrace", @"DPSsetinputstate: %d : %d", st, win);
if ((generic.wm & XGWM_WINDOWMAKER) != 0)
{