mirror of
https://github.com/gnustep/libs-back.git
synced 2025-04-22 15:31:14 +00:00
Some more style/offset checking.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@23613 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
02c6dc3ba2
commit
336a4fd4b9
4 changed files with 507 additions and 42 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
2006-09-25 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/x11/XGGeneric.h: Extra fielkd to flag when style offsets
|
||||
are known.
|
||||
* Source/x11/XGServerEvent.m: Add a lot more debug logging for
|
||||
reparenting. Ignore and log changes to 'known' style offsets.
|
||||
* Source/x11/XGServerWindow.m: On startup we now check to see if
|
||||
style offsets have been recorded in the root window, and if not
|
||||
we briefly create a test window of each style to determine style
|
||||
offsets, so we know what the offsets are for each style before
|
||||
anything attempts to use them.
|
||||
|
||||
2006-09-24 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/x11/XGServerEvent.m: Use #if to disable old window exposure
|
||||
|
|
|
@ -59,6 +59,7 @@ typedef struct {
|
|||
short r; // offset from right
|
||||
short t; // offset from top
|
||||
short b; // offset from bottom
|
||||
BOOL known; // obtained from Reparent event or just guessed?
|
||||
} Offsets;
|
||||
|
||||
/*
|
||||
|
|
|
@ -1307,36 +1307,43 @@ static int check_modifier (XEvent *xEvent, KeySym key_sym,
|
|||
generic.cachedWindow
|
||||
= [XGServer _windowForXWindow:xEvent.xreparent.window];
|
||||
}
|
||||
if (cWin != 0)
|
||||
{
|
||||
cWin->parent = xEvent.xreparent.parent;
|
||||
}
|
||||
|
||||
if (cWin != 0 && xEvent.xreparent.parent != cWin->root
|
||||
&& (xEvent.xreparent.x != 0 || xEvent.xreparent.y != 0))
|
||||
{
|
||||
Window parent = xEvent.xreparent.parent;
|
||||
XWindowAttributes wattr;
|
||||
float l;
|
||||
float r;
|
||||
float t;
|
||||
float b;
|
||||
Offsets *o;
|
||||
|
||||
/* FIXME: if offsets have changed, we should go through window
|
||||
list and fix up hints */
|
||||
|
||||
/* Get the WM offset info which we hope is the same
|
||||
* for all parented windows
|
||||
* for all parented windows with the same style.
|
||||
* The coordinates in the event are insufficient to determine
|
||||
* the offsets as the new parent window may have a border,
|
||||
* so we must get the attributes of that window and use them
|
||||
* to determine our offsets.
|
||||
*/
|
||||
XGetWindowAttributes(dpy, parent, &wattr);
|
||||
o = generic.offsets + (cWin->win_attrs.window_style & 15);
|
||||
o->l = xEvent.xreparent.x + wattr.border_width;
|
||||
o->t = xEvent.xreparent.y + wattr.border_width;
|
||||
NSDebugLLog(@"NSEvent", @"Parent border,width,height %d,%d,%d\n",
|
||||
wattr.border_width, wattr.width, wattr.height);
|
||||
l = xEvent.xreparent.x + wattr.border_width;
|
||||
t = xEvent.xreparent.y + wattr.border_width;
|
||||
|
||||
/* Find total parent size and subtract window size and
|
||||
* top-left-corner offset to determine bottom-right-corner
|
||||
* offset.
|
||||
*/
|
||||
o->r = wattr.width + wattr.border_width * 2;
|
||||
o->r -= (cWin->xframe.size.width + o->l);
|
||||
o->b = wattr.height + wattr.border_width * 2;
|
||||
o->b -= (cWin->xframe.size.height + o->t);
|
||||
r = wattr.width + wattr.border_width * 2;
|
||||
r -= (cWin->xframe.size.width + l);
|
||||
b = wattr.height + wattr.border_width * 2;
|
||||
b -= (cWin->xframe.size.height + t);
|
||||
|
||||
// Some window manager e.g. KDE2 put in multiple windows,
|
||||
// so we have to find the right parent, closest to root
|
||||
|
@ -1349,6 +1356,8 @@ static int check_modifier (XEvent *xEvent, KeySym key_sym,
|
|||
{
|
||||
Window new_parent = parent;
|
||||
|
||||
r = wattr.width + wattr.border_width * 2;
|
||||
b = wattr.height + wattr.border_width * 2;
|
||||
while (new_parent && (new_parent != cWin->root))
|
||||
{
|
||||
Window root;
|
||||
|
@ -1374,21 +1383,69 @@ static int check_modifier (XEvent *xEvent, KeySym key_sym,
|
|||
}
|
||||
if (new_parent && new_parent != cWin->root)
|
||||
{
|
||||
XWindowAttributes wattr;
|
||||
XGetWindowAttributes(dpy, parent, &wattr);
|
||||
if (wattr.x || wattr.y)
|
||||
{
|
||||
o->l += wattr.x + wattr.border_width;
|
||||
o->t += wattr.y + wattr.border_width;
|
||||
o->r = wattr.width + wattr.border_width * 2;
|
||||
o->b = wattr.height + wattr.border_width * 2;
|
||||
}
|
||||
XWindowAttributes pattr;
|
||||
|
||||
XGetWindowAttributes(dpy, parent, &pattr);
|
||||
l += pattr.x + pattr.border_width;
|
||||
t += pattr.y + pattr.border_width;
|
||||
r = pattr.width + pattr.border_width * 2;
|
||||
b = pattr.height + pattr.border_width * 2;
|
||||
}
|
||||
} /* while */
|
||||
o->r -= (cWin->xframe.size.width + o->l);
|
||||
o->b -= (cWin->xframe.size.height + o->t);
|
||||
r -= (cWin->xframe.size.width + l);
|
||||
b -= (cWin->xframe.size.height + t);
|
||||
} /* generic.flags.doubleParentWindow */
|
||||
cWin->parent = parent;
|
||||
|
||||
o = generic.offsets + (cWin->win_attrs.window_style & 15);
|
||||
if (o->known == NO)
|
||||
{
|
||||
o->l = l;
|
||||
o->r = r;
|
||||
o->t = t;
|
||||
o->b = b;
|
||||
o->known = YES;
|
||||
/* FIXME: if offsets have changed, from previously guessed
|
||||
* versions, we should go through window list and fix up
|
||||
* hints.
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOL changed = NO;
|
||||
|
||||
if (l != o->l)
|
||||
{
|
||||
NSLog(@"Ignore left offset change from %d to %d",
|
||||
(int)o->l, (int)l);
|
||||
changed = YES;
|
||||
}
|
||||
if (r != o->r)
|
||||
{
|
||||
NSLog(@"Ignore right offset change from %d to %d",
|
||||
(int)o->r, (int)r);
|
||||
changed = YES;
|
||||
}
|
||||
if (t != o->t)
|
||||
{
|
||||
NSLog(@"Ignore top offset change from %d to %d",
|
||||
(int)o->t, (int)t);
|
||||
changed = YES;
|
||||
}
|
||||
if (b != o->b)
|
||||
{
|
||||
NSLog(@"Ignore bottom offset change from %d to %d",
|
||||
(int)o->b, (int)b);
|
||||
changed = YES;
|
||||
}
|
||||
if (changed == YES)
|
||||
{
|
||||
NSLog(@"Reparent was with offset %d %d\n",
|
||||
xEvent.xreparent.x, xEvent.xreparent.y);
|
||||
NSLog(@"Parent border,width,height %d,%d,%d\n",
|
||||
wattr.border_width, wattr.width, wattr.height);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1416,7 +1473,7 @@ static int check_modifier (XEvent *xEvent, KeySym key_sym,
|
|||
|
||||
// We shouldn't get here unless we forgot to trap an event above
|
||||
default:
|
||||
#ifdef XSHM
|
||||
#ifdef XSHM
|
||||
if (xEvent.type == XShmGetEventBase(dpy)+ShmCompletion
|
||||
&& [gcontext respondsToSelector: @selector(gotShmCompletion:)])
|
||||
{
|
||||
|
@ -1424,7 +1481,7 @@ static int check_modifier (XEvent *xEvent, KeySym key_sym,
|
|||
((XShmCompletionEvent *)&xEvent)->drawable];
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
NSLog(@"Received an untrapped event\n");
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -76,6 +76,10 @@ static gswindow_device_t *grab_window = NULL;
|
|||
static NSMapTable *windowmaps = NULL;
|
||||
static NSMapTable *windowtags = NULL;
|
||||
|
||||
/* Track used window numbers */
|
||||
static int last_win_num = 0;
|
||||
|
||||
|
||||
@interface NSCursor (BackendPrivate)
|
||||
- (void *)_cid;
|
||||
@end
|
||||
|
@ -354,6 +358,7 @@ static void setWindowHintsForStyle (Display *dpy, Window window,
|
|||
@end
|
||||
|
||||
@interface XGServer (WindowOps)
|
||||
- (gswindow_device_t *) _rootWindowForScreen: (int)screen;
|
||||
- (void) styleoffsets: (float *) l : (float *) r : (float *) t : (float *) b
|
||||
: (unsigned int) style : (Window) win;
|
||||
@end
|
||||
|
@ -522,6 +527,301 @@ static void setWindowHintsForStyle (Display *dpy, Window window,
|
|||
}
|
||||
|
||||
|
||||
- (BOOL) _checkStyle: (unsigned)style
|
||||
{
|
||||
gswindow_device_t *window;
|
||||
gswindow_device_t *root;
|
||||
NSRect frame = NSMakeRect(100,100,100,100);
|
||||
XGCValues values;
|
||||
unsigned long valuemask;
|
||||
XClassHint classhint;
|
||||
RContext *context;
|
||||
XEvent xEvent;
|
||||
|
||||
root = [self _rootWindowForScreen: 0];
|
||||
context = [self xrContextForScreen: 0];
|
||||
|
||||
window = objc_malloc(sizeof(gswindow_device_t));
|
||||
memset(window, '\0', sizeof(gswindow_device_t));
|
||||
window->display = dpy;
|
||||
window->screen = 0;
|
||||
|
||||
window->win_attrs.flags |= GSWindowStyleAttr;
|
||||
window->win_attrs.window_style = style;
|
||||
|
||||
window->xframe = frame;
|
||||
window->type = NSBackingStoreNonretained;
|
||||
window->root = root->ident;
|
||||
window->parent = root->ident;
|
||||
window->depth = context->depth;
|
||||
window->xwn_attrs.border_pixel = context->black;
|
||||
window->xwn_attrs.background_pixel = context->white;
|
||||
window->xwn_attrs.colormap = context->cmap;
|
||||
|
||||
window->ident = XCreateWindow(dpy, window->root,
|
||||
NSMinX(frame), NSMinY(frame),
|
||||
NSWidth(frame), NSHeight(frame),
|
||||
0,
|
||||
context->depth,
|
||||
CopyFromParent,
|
||||
context->visual,
|
||||
(CWColormap | CWBackPixel | CWBorderPixel),
|
||||
&window->xwn_attrs);
|
||||
|
||||
/*
|
||||
* Mark this as a GNUstep app with the current application name.
|
||||
*/
|
||||
classhint.res_name = rootName;
|
||||
classhint.res_class = "GNUstep";
|
||||
XSetClassHint(dpy, window->ident, &classhint);
|
||||
|
||||
window->xwn_attrs.save_under = False;
|
||||
window->xwn_attrs.override_redirect = False;
|
||||
window->map_state = IsUnmapped;
|
||||
window->visibility = -1;
|
||||
|
||||
// Create an X GC for the content view set it's colors
|
||||
values.foreground = window->xwn_attrs.background_pixel;
|
||||
values.background = window->xwn_attrs.background_pixel;
|
||||
values.function = GXcopy;
|
||||
valuemask = (GCForeground | GCBackground | GCFunction);
|
||||
window->gc = XCreateGC(dpy, window->ident, valuemask, &values);
|
||||
|
||||
/* Set the X event mask
|
||||
*/
|
||||
XSelectInput(dpy, window->ident, ExposureMask
|
||||
| KeyPressMask
|
||||
| KeyReleaseMask
|
||||
| ButtonPressMask
|
||||
| ButtonReleaseMask
|
||||
| ButtonMotionMask
|
||||
| StructureNotifyMask
|
||||
| PointerMotionMask
|
||||
| EnterWindowMask
|
||||
| LeaveWindowMask
|
||||
| FocusChangeMask
|
||||
// | PropertyChangeMask
|
||||
// | ColormapChangeMask
|
||||
| KeymapStateMask
|
||||
| VisibilityChangeMask
|
||||
);
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/*
|
||||
* Prepare size/position hints, but don't set them now - ordering
|
||||
* the window in should automatically do it.
|
||||
*/
|
||||
window->siz_hints.x = NSMinX(frame);
|
||||
window->siz_hints.y = NSMinY(frame);
|
||||
window->siz_hints.width = NSWidth(frame);
|
||||
window->siz_hints.height = NSHeight(frame);
|
||||
window->siz_hints.flags = USPosition|PPosition|USSize|PSize;
|
||||
|
||||
// Always send GNUstepWMAttributes
|
||||
/* Warning ... X-bug .. when we specify 32bit data X actually expects data
|
||||
* of type 'long' or 'unsigned long' even on machines where those types
|
||||
* hold 64bit values.
|
||||
*/
|
||||
XChangeProperty(dpy, window->ident, generic.win_decor_atom,
|
||||
generic.win_decor_atom, 32, PropModeReplace,
|
||||
(unsigned char *)&window->win_attrs,
|
||||
sizeof(GNUstepWMAttributes)/sizeof(CARD32));
|
||||
|
||||
// send to the WM window style hints
|
||||
if ((generic.wm & XGWM_WINDOWMAKER) == 0)
|
||||
{
|
||||
setWindowHintsForStyle (dpy, window->ident, style);
|
||||
}
|
||||
|
||||
// Use the globally active input mode
|
||||
window->gen_hints.flags = InputHint;
|
||||
window->gen_hints.input = False;
|
||||
// All the windows of a GNUstep application belong to one group.
|
||||
window->gen_hints.flags |= WindowGroupHint;
|
||||
window->gen_hints.window_group = ROOT;
|
||||
|
||||
/*
|
||||
* Prepare the protocols supported by the window.
|
||||
* These protocols should be set on the window when it is ordered in.
|
||||
*/
|
||||
window->numProtocols = 0;
|
||||
window->protocols[window->numProtocols++] = generic.take_focus_atom;
|
||||
window->protocols[window->numProtocols++] = generic.delete_win_atom;
|
||||
window->protocols[window->numProtocols++] = generic.net_wm_ping_atom;
|
||||
if ((generic.wm & XGWM_WINDOWMAKER) != 0)
|
||||
{
|
||||
window->protocols[window->numProtocols++] = generic.miniaturize_atom;
|
||||
}
|
||||
// FIXME Add ping protocol for EWMH
|
||||
XSetWMProtocols(dpy, window->ident, window->protocols, window->numProtocols);
|
||||
|
||||
window->exposedRects = [NSMutableArray new];
|
||||
window->region = XCreateRegion();
|
||||
window->buffer = 0;
|
||||
window->alpha_buffer = 0;
|
||||
window->ic = 0;
|
||||
|
||||
// make sure that new window has the correct cursor
|
||||
[self _initializeCursorForXWindow: window->ident];
|
||||
|
||||
/*
|
||||
* FIXME - should this be protected by a lock for thread safety?
|
||||
* generate a unique tag for this new window.
|
||||
*/
|
||||
do
|
||||
{
|
||||
last_win_num++;
|
||||
}
|
||||
while (last_win_num == 0 || WINDOW_WITH_TAG(last_win_num) != 0);
|
||||
window->number = last_win_num;
|
||||
|
||||
// Insert window into the mapping
|
||||
NSMapInsert(windowmaps, (void*)(uintptr_t)window->ident, window);
|
||||
NSMapInsert(windowtags, (void*)(uintptr_t)window->number, window);
|
||||
[self _setWindowOwnedByServer: window->number];
|
||||
[self orderwindow: NSWindowAbove : 0 : window->number];
|
||||
|
||||
XSync(dpy, False);
|
||||
while (XPending(dpy) > 0)
|
||||
{
|
||||
XNextEvent(dpy, &xEvent);
|
||||
|
||||
switch (xEvent.type)
|
||||
{
|
||||
case ReparentNotify:
|
||||
NSDebugLLog(@"Offset", @"%d ReparentNotify - offset %d %d\n",
|
||||
xEvent.xreparent.window, xEvent.xreparent.x,
|
||||
xEvent.xreparent.y);
|
||||
window->parent = xEvent.xreparent.parent;
|
||||
|
||||
if (window != 0 && xEvent.xreparent.parent != window->root
|
||||
&& (xEvent.xreparent.x != 0 || xEvent.xreparent.y != 0))
|
||||
{
|
||||
Window parent = xEvent.xreparent.parent;
|
||||
XWindowAttributes wattr;
|
||||
float l;
|
||||
float r;
|
||||
float t;
|
||||
float b;
|
||||
Offsets *o;
|
||||
|
||||
/* Get the WM offset info which we hope is the same
|
||||
* for all parented windows with the same style.
|
||||
* The coordinates in the event are insufficient to determine
|
||||
* the offsets as the new parent window may have a border,
|
||||
* so we must get the attributes of that window and use them
|
||||
* to determine our offsets.
|
||||
*/
|
||||
XGetWindowAttributes(dpy, parent, &wattr);
|
||||
NSDebugLLog(@"Offset", @"Parent border,width,height %d,%d,%d\n",
|
||||
wattr.border_width, wattr.width, wattr.height);
|
||||
l = xEvent.xreparent.x + wattr.border_width;
|
||||
t = xEvent.xreparent.y + wattr.border_width;
|
||||
|
||||
/* Find total parent size and subtract window size and
|
||||
* top-left-corner offset to determine bottom-right-corner
|
||||
* offset.
|
||||
*/
|
||||
r = wattr.width + wattr.border_width * 2;
|
||||
r -= (window->xframe.size.width + l);
|
||||
b = wattr.height + wattr.border_width * 2;
|
||||
b -= (window->xframe.size.height + t);
|
||||
|
||||
// Some window manager e.g. KDE2 put in multiple windows,
|
||||
// so we have to find the right parent, closest to root
|
||||
/* FIXME: This section of code has caused problems with
|
||||
certain users. An X error occurs in XQueryTree and
|
||||
later a seg fault in XFree. It's 'commented' out for
|
||||
now unless you set the default 'GSDoubleParentWindows'
|
||||
*/
|
||||
if (generic.flags.doubleParentWindow)
|
||||
{
|
||||
Window new_parent = parent;
|
||||
|
||||
r = wattr.width + wattr.border_width * 2;
|
||||
b = wattr.height + wattr.border_width * 2;
|
||||
while (new_parent && (new_parent != window->root))
|
||||
{
|
||||
Window root;
|
||||
Window *children;
|
||||
unsigned int nchildren;
|
||||
|
||||
parent = new_parent;
|
||||
NSLog(@"QueryTree window is %d (root %d cwin root %d)",
|
||||
parent, root, window->root);
|
||||
if (!XQueryTree(dpy, parent, &root, &new_parent,
|
||||
&children, &nchildren))
|
||||
{
|
||||
new_parent = None;
|
||||
if (children)
|
||||
{
|
||||
NSLog(@"Bad pointer from failed X call?");
|
||||
children = 0;
|
||||
}
|
||||
}
|
||||
if (children)
|
||||
{
|
||||
XFree(children);
|
||||
}
|
||||
if (new_parent && new_parent != window->root)
|
||||
{
|
||||
XGetWindowAttributes(dpy, parent, &wattr);
|
||||
l += wattr.x + wattr.border_width;
|
||||
t += wattr.y + wattr.border_width;
|
||||
r = wattr.width + wattr.border_width * 2;
|
||||
b = wattr.height + wattr.border_width * 2;
|
||||
}
|
||||
} /* while */
|
||||
r -= (window->xframe.size.width + l);
|
||||
b -= (window->xframe.size.height + t);
|
||||
} /* generic.flags.doubleParentWindow */
|
||||
|
||||
o = generic.offsets + (window->win_attrs.window_style & 15);
|
||||
o->l = l;
|
||||
o->r = r;
|
||||
o->t = t;
|
||||
o->b = b;
|
||||
NSDebugLLog(@"Offset",
|
||||
@"Style %d lrtb set to %d,%d,%d,%d\n",
|
||||
style, (int)l, (int)r, (int)t, (int)b);
|
||||
if (o->known == YES)
|
||||
{
|
||||
if (l != o->l)
|
||||
NSLog(@"Left offset change from %d to %d",
|
||||
(int)o->l, (int)l);
|
||||
if (r != o->r)
|
||||
NSLog(@"Right offset change from %d to %d",
|
||||
(int)o->r, (int)r);
|
||||
if (t != o->t)
|
||||
NSLog(@"Top offset change from %d to %d",
|
||||
(int)o->t, (int)t);
|
||||
if (b != o->b)
|
||||
NSLog(@"Bottom offset change from %d to %d",
|
||||
(int)o->b, (int)b);
|
||||
}
|
||||
o->known = YES;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[self termwindow: window->number];
|
||||
XSync(dpy, False);
|
||||
while (XPending(dpy) > 0) XNextEvent(dpy, &xEvent);
|
||||
if (generic.offsets[(window->win_attrs.window_style & 15)].known == NO)
|
||||
{
|
||||
NSLog(@"Failed to determine offsets for style %d", style);
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (XGWMProtocols) _checkWindowManager
|
||||
{
|
||||
int wmflags;
|
||||
|
@ -661,7 +961,7 @@ static void setWindowHintsForStyle (Display *dpy, Window window,
|
|||
return wmflags;
|
||||
}
|
||||
|
||||
- (gswindow_device_t *)_rootWindowForScreen: (int)screen
|
||||
- (gswindow_device_t *) _rootWindowForScreen: (int)screen
|
||||
{
|
||||
int x, y;
|
||||
unsigned int width, height;
|
||||
|
@ -689,8 +989,8 @@ static void setWindowHintsForStyle (Display *dpy, Window window,
|
|||
&window->border, &window->depth);
|
||||
|
||||
window->xframe = NSMakeRect(x, y, width, height);
|
||||
NSMapInsert (windowtags, (void*)window->number, window);
|
||||
NSMapInsert (windowmaps, (void*)window->ident, window);
|
||||
NSMapInsert (windowtags, (void*)(uintptr_t)window->number, window);
|
||||
NSMapInsert (windowmaps, (void*)(uintptr_t)window->ident, window);
|
||||
return window;
|
||||
}
|
||||
|
||||
|
@ -833,7 +1133,8 @@ static void setWindowHintsForStyle (Display *dpy, Window window,
|
|||
defs = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
if ([defs objectForKey: @"GSX11HandlesWindowDecorations"])
|
||||
handlesWindowDecorations = [defs boolForKey: @"GSX11HandlesWindowDecorations"];
|
||||
handlesWindowDecorations
|
||||
= [defs boolForKey: @"GSX11HandlesWindowDecorations"];
|
||||
|
||||
generic.flags.useWindowMakerIcons = NO;
|
||||
if ((generic.wm & XGWM_WINDOWMAKER) != 0)
|
||||
|
@ -957,6 +1258,99 @@ static void setWindowHintsForStyle (Display *dpy, Window window,
|
|||
32, PropModeReplace,
|
||||
(unsigned char*)&pid, 1);
|
||||
}
|
||||
|
||||
/* We need to determine the offsets between the actual decorated window
|
||||
* and the window we draw into.
|
||||
*/
|
||||
if (handlesWindowDecorations == YES)
|
||||
{
|
||||
static Atom _offsets_name = None;
|
||||
unsigned i;
|
||||
int count;
|
||||
uint16_t *offsets;
|
||||
|
||||
/* Offsets for NSBorderlessWindowMask *should* always be zero.
|
||||
* We record them in the offsets block only for consistency.
|
||||
*/
|
||||
generic.offsets[0].l = 0.0;
|
||||
generic.offsets[0].r = 0.0;
|
||||
generic.offsets[0].t = 0.0;
|
||||
generic.offsets[0].b = 0.0;
|
||||
generic.offsets[0].known = YES;
|
||||
|
||||
/* We trust the _GNUSTEP_FRAME_OFFSETS values set on the root window
|
||||
* of the X server if present.
|
||||
* Of course, these could have changed if the window manager has
|
||||
* changed. (FIXME)
|
||||
* The GSIgnoreRootOffsets default turns off this trusting approach.
|
||||
*/
|
||||
if (_offsets_name == None)
|
||||
{
|
||||
_offsets_name = XInternAtom(dpy, "_GNUSTEP_FRAME_OFFSETS", False);
|
||||
}
|
||||
if ([defs boolForKey: @"GSIgnoreRootOffsets"] == YES)
|
||||
{
|
||||
offsets = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
offsets = (uint16_t *)PropGetCheckProperty(dpy,
|
||||
DefaultRootWindow(dpy), _offsets_name, XA_CARDINAL, 16, 60, &count);
|
||||
}
|
||||
|
||||
if (offsets == 0)
|
||||
{
|
||||
BOOL ok = YES;
|
||||
|
||||
/* No offsets available on the root window ... so we test each
|
||||
* style of window to determine its offsets.
|
||||
*/
|
||||
for (i = 1; i < 16; i++)
|
||||
{
|
||||
if ([self _checkStyle: i] == NO)
|
||||
{
|
||||
ok = NO; // test failed for this style
|
||||
}
|
||||
}
|
||||
|
||||
if (ok == YES)
|
||||
{
|
||||
uint16_t off[60];
|
||||
|
||||
/* We have obtained all the offsets, so we store them to
|
||||
* the root window so that other GNUstep applications don't
|
||||
* need to test to determine offsets.
|
||||
*/
|
||||
count = 0;
|
||||
for (i = 1; i < 16; i++)
|
||||
{
|
||||
off[count++] = (uint16_t)generic.offsets[i].l;
|
||||
off[count++] = (uint16_t)generic.offsets[i].r;
|
||||
off[count++] = (uint16_t)generic.offsets[i].t;
|
||||
off[count++] = (uint16_t)generic.offsets[i].b;
|
||||
}
|
||||
XChangeProperty(dpy, DefaultRootWindow(dpy),
|
||||
_offsets_name, XA_CARDINAL, 16, PropModeReplace,
|
||||
(unsigned char *)off, 60);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Got offsets from the root window.
|
||||
* Let's copy them into our local table.
|
||||
*/
|
||||
count = 0;
|
||||
for (i = 1; i < 16; i++)
|
||||
{
|
||||
generic.offsets[i].l = (float)(offsets[count++]);
|
||||
generic.offsets[i].r = (float)(offsets[count++]);
|
||||
generic.offsets[i].t = (float)(offsets[count++]);
|
||||
generic.offsets[i].b = (float)(offsets[count++]);
|
||||
generic.offsets[i].known = YES;
|
||||
}
|
||||
XFree(offsets);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Destroys all the windows and other window resources that belong to
|
||||
|
@ -1153,12 +1547,11 @@ static void setWindowHintsForStyle (Display *dpy, Window window,
|
|||
32, PropModeReplace,
|
||||
(unsigned char *)iconPropertyData, iconSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (int) window: (NSRect)frame : (NSBackingStoreType)type : (unsigned int)style
|
||||
: (int)screen
|
||||
{
|
||||
static int last_win_num = 0;
|
||||
gswindow_device_t *window;
|
||||
gswindow_device_t *root;
|
||||
XGCValues values;
|
||||
|
@ -1338,16 +1731,16 @@ static void setWindowHintsForStyle (Display *dpy, Window window,
|
|||
window->number = last_win_num;
|
||||
|
||||
// Insert window into the mapping
|
||||
NSMapInsert(windowmaps, (void*)window->ident, window);
|
||||
NSMapInsert(windowtags, (void*)window->number, window);
|
||||
NSMapInsert(windowmaps, (void*)(uintptr_t)window->ident, window);
|
||||
NSMapInsert(windowtags, (void*)(uintptr_t)window->number, window);
|
||||
[self _setWindowOwnedByServer: window->number];
|
||||
|
||||
return window->number;
|
||||
}
|
||||
|
||||
- (int) nativeWindow: (void *)winref : (NSRect*)frame : (NSBackingStoreType*)type
|
||||
: (unsigned int*)style : (int*)screen
|
||||
{
|
||||
static int last_win_num = 0;
|
||||
gswindow_device_t *window;
|
||||
gswindow_device_t *root;
|
||||
XGCValues values;
|
||||
|
@ -1454,8 +1847,8 @@ static void setWindowHintsForStyle (Display *dpy, Window window,
|
|||
window->number = last_win_num;
|
||||
|
||||
// Insert window into the mapping
|
||||
NSMapInsert(windowmaps, (void*)window->ident, window);
|
||||
NSMapInsert(windowtags, (void*)window->number, window);
|
||||
NSMapInsert(windowmaps, (void*)(uintptr_t)window->ident, window);
|
||||
NSMapInsert(windowtags, (void*)(uintptr_t)window->number, window);
|
||||
[self _setWindowOwnedByServer: window->number];
|
||||
return window->number;
|
||||
}
|
||||
|
@ -1573,11 +1966,9 @@ static void setWindowHintsForStyle (Display *dpy, Window window,
|
|||
}
|
||||
}
|
||||
|
||||
if (style == NSBorderlessWindowMask
|
||||
|| (style & NSIconWindowMask) || (style & NSMiniWindowMask))
|
||||
if ((style & NSIconWindowMask) || (style & NSMiniWindowMask))
|
||||
{
|
||||
*l = *r = *t = *b = 0.0;
|
||||
return;
|
||||
style = NSBorderlessWindowMask;
|
||||
}
|
||||
|
||||
/* Next try to get the offset information that we have obtained from
|
||||
|
@ -1586,7 +1977,7 @@ static void setWindowHintsForStyle (Display *dpy, Window window,
|
|||
guess.
|
||||
*/
|
||||
o = generic.offsets + (style & 15);
|
||||
if (o->l || o->r || o->t || o->b)
|
||||
if (o->known == YES)
|
||||
{
|
||||
*l = o->l;
|
||||
*r = o->r;
|
||||
|
@ -1595,8 +1986,12 @@ static void setWindowHintsForStyle (Display *dpy, Window window,
|
|||
NSDebugLLog(@"Frame",
|
||||
@"Window %d, offsets %f, %f, %f, %f",
|
||||
win, *l, *r, *t, *b);
|
||||
return;
|
||||
}
|
||||
else if ((generic.wm & XGWM_WINDOWMAKER) != 0)
|
||||
|
||||
NSLog(@"styleoffsets ... guessing offsets\n");
|
||||
|
||||
if ((generic.wm & XGWM_WINDOWMAKER) != 0)
|
||||
{
|
||||
*l = *r = *t = *b = 1.0;
|
||||
if (NSResizableWindowMask & style)
|
||||
|
|
Loading…
Reference in a new issue