|
@@ -2,39 +2,82 @@
|
2
|
2
|
|
3
|
3
|
using namespace slop;
|
4
|
4
|
|
5
|
|
-glm::vec4 slop::getWindowGeometry( Window win, bool removeDecoration) {
|
6
|
|
- XWindowAttributes attr;
|
7
|
|
- XGetWindowAttributes( x11->display, win, &attr );
|
8
|
|
- unsigned int width = attr.width;
|
9
|
|
- unsigned int height = attr.height;
|
10
|
|
- unsigned int border = attr.border_width;
|
11
|
|
- int x, y;
|
12
|
|
- Window junk;
|
13
|
|
- XTranslateCoordinates( x11->display, win, attr.root, -attr.border_width, -attr.border_width, &x, &y, &junk );
|
14
|
|
- if ( !removeDecoration ) {
|
|
5
|
+glm::vec4 slop::getWindowGeometry( Window win, bool removeDecoration ) {
|
|
6
|
+ // First lets check for if we're a window manager frame.
|
|
7
|
+ Window root, parent;
|
|
8
|
+ Window* children;
|
|
9
|
+ unsigned int num_children;
|
|
10
|
+ XQueryTree( x11->display, win, &root, &parent, &children, &num_children);
|
|
11
|
+
|
|
12
|
+ // To do that, we check if our top level child happens to have the _NET_FRAME_EXTENTS atom.
|
|
13
|
+ unsigned char *data;
|
|
14
|
+ Atom type_return;
|
|
15
|
+ unsigned long nitems_return;
|
|
16
|
+ unsigned long bytes_after_return;
|
|
17
|
+ int format_return;
|
|
18
|
+ bool window_frame = false;
|
|
19
|
+ Window actualWindow = win;
|
|
20
|
+ if ( num_children > 0 && XGetWindowProperty( x11->display, children[num_children-1], XInternAtom( x11->display, "_NET_FRAME_EXTENTS", False),
|
|
21
|
+ 0, LONG_MAX, False, XA_CARDINAL, &type_return,
|
|
22
|
+ &format_return, &nitems_return, &bytes_after_return,
|
|
23
|
+ &data) == Success ) {
|
|
24
|
+ if ((type_return == XA_CARDINAL) && (format_return == 32) && (nitems_return == 4) && (data)) {
|
|
25
|
+ actualWindow = children[num_children-1];
|
|
26
|
+ window_frame = true;
|
|
27
|
+ }
|
|
28
|
+ }
|
|
29
|
+
|
|
30
|
+ // If we actually don't want the window frame (decoration), we just actually grab the decoration's innards.
|
|
31
|
+ // And ignore all of the _NET_FRAME_EXTENTS information.
|
|
32
|
+ if ( actualWindow != win && removeDecoration ) {
|
|
33
|
+ win = actualWindow;
|
|
34
|
+ window_frame = false;
|
|
35
|
+ }
|
|
36
|
+
|
|
37
|
+ // If we're a window frame, we actually get the dimensions of the child window, then add the _NET_FRAME_EXTENTS to it.
|
|
38
|
+ // (then add the border width of the window frame after that.)
|
|
39
|
+ if ( window_frame ) {
|
|
40
|
+ // First lets grab the border width.
|
|
41
|
+ XWindowAttributes frameattr;
|
|
42
|
+ XGetWindowAttributes( x11->display, win, &frameattr );
|
|
43
|
+ // Then lets grab the dims of the child window.
|
|
44
|
+ XWindowAttributes attr;
|
|
45
|
+ XGetWindowAttributes( x11->display, actualWindow, &attr );
|
|
46
|
+ unsigned int width = attr.width;
|
|
47
|
+ unsigned int height = attr.height;
|
|
48
|
+ // We combine both border widths.
|
|
49
|
+ unsigned int border = attr.border_width+frameattr.border_width;
|
|
50
|
+ int x, y;
|
|
51
|
+ // Gotta translate them into root coords, we can adjust for the border width here.
|
|
52
|
+ Window junk;
|
|
53
|
+ XTranslateCoordinates( x11->display, actualWindow, attr.root, -border, -border, &x, &y, &junk );
|
|
54
|
+ width += border*2;
|
|
55
|
+ height += border*2;
|
|
56
|
+ // Now uh, remember that _NET_FRAME_EXTENTS stuff? That's the window frame information.
|
|
57
|
+ // We HAVE to do this because mutter likes to mess with window sizes with shadows and stuff.
|
|
58
|
+ unsigned long* ldata = (unsigned long*)data;
|
|
59
|
+ width += ldata[0] + ldata[1];
|
|
60
|
+ height += ldata[2] + ldata[3];
|
|
61
|
+ x -= ldata[0];
|
|
62
|
+ y -= ldata[2];
|
|
63
|
+ return glm::vec4( x, y, width, height );
|
|
64
|
+ } else {
|
|
65
|
+ // Either the WM is malfunctioning, or the window specified isn't a window manager frame.
|
|
66
|
+ // so we just rely on X to give a decent geometry.
|
|
67
|
+ XWindowAttributes attr;
|
|
68
|
+ XGetWindowAttributes( x11->display, win, &attr );
|
|
69
|
+ unsigned int width = attr.width;
|
|
70
|
+ unsigned int height = attr.height;
|
|
71
|
+ // We combine both border widths.
|
|
72
|
+ unsigned int border = attr.border_width;
|
|
73
|
+ int x, y;
|
|
74
|
+ // Gotta translate them into root coords, we can adjust for the border width here.
|
|
75
|
+ Window junk;
|
|
76
|
+ XTranslateCoordinates( x11->display, win, attr.root, -border, -border, &x, &y, &junk );
|
15
|
77
|
width += border*2;
|
16
|
78
|
height += border*2;
|
17
|
79
|
return glm::vec4( x, y, width, height );
|
18
|
80
|
}
|
19
|
|
- // This is required to be defined by the window manager, so we can assume it exists.
|
20
|
|
- Atom actual_type;
|
21
|
|
- int actual_format;
|
22
|
|
- unsigned long nitems, bytes_after;
|
23
|
|
- unsigned char *data;
|
24
|
|
- int result = XGetWindowProperty(x11->display, win,
|
25
|
|
- XInternAtom(x11->display, "_NET_FRAME_EXTENTS", true),
|
26
|
|
- 0, 4, False, AnyPropertyType,
|
27
|
|
- &actual_type, &actual_format, &nitems, &bytes_after, &data);
|
28
|
|
- if ( result == Success ) {
|
29
|
|
- // Make sure we got the data we expect...
|
30
|
|
- if ((nitems == 4) && (bytes_after == 0)) {
|
31
|
|
- x += (int)data[0];
|
32
|
|
- width -= (int)data[1];
|
33
|
|
- y += (int)data[2];
|
34
|
|
- height -= (int)data[3];
|
35
|
|
- }
|
36
|
|
- }
|
37
|
|
- return glm::vec4( x, y, width, height );
|
38
|
81
|
}
|
39
|
82
|
|
40
|
83
|
bool X11::hasCompositor() {
|