diff --git a/ChangeLog b/ChangeLog
index cccdc3f..5a71f8d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2004-06-26 13:04 Alexander Malmberg
+
+ * 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
* Source/win32/WIN32Server.m (-findWindowAt:windowRef:excluding:)
diff --git a/Documentation/Back/DefaultsSummary.gsdoc b/Documentation/Back/DefaultsSummary.gsdoc
index 3f03997..9ec427d 100644
--- a/Documentation/Back/DefaultsSummary.gsdoc
+++ b/Documentation/Back/DefaultsSummary.gsdoc
@@ -110,6 +110,16 @@
OverTheSpot
.
+
[Xlib backend only]
diff --git a/Source/x11/XGServerEvent.m b/Source/x11/XGServerEvent.m
index 5f1becf..1eed9c7 100644
--- a/Source/x11/XGServerEvent.m
+++ b/Source/x11/XGServerEvent.m
@@ -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
diff --git a/Source/x11/XGServerWindow.m b/Source/x11/XGServerWindow.m
index 01a7142..a00a8ea 100644
--- a/Source/x11/XGServerWindow.m
+++ b/Source/x11/XGServerWindow.m
@@ -31,6 +31,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -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)
{