1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
4 # include "../config.h"
9 #include <X11/extensions/shape.h>
15 #include "otk/display.hh"
19 OBFrame::OBFrame(const OBClient
*client
, const otk::Style
*style
)
21 _screen(otk::OBDisplay::screenInfo(client
->screen()))
29 _window
= createFrame();
42 void OBFrame::loadStyle(const otk::Style
*style
)
46 // if a style was previously set, then 'replace' is true, cause we're
48 // NOTE: if this is false, then DO NOT DO SHIT WITH _window, it doesnt exist
49 bool replace
= (_style
);
52 // XXX: do shit here whatever
57 // XXX: load shit like this from the style!
58 _size
.left
= _size
.top
= _size
.bottom
= _size
.right
= 2;
63 XSetWindowBorderWidth(otk::OBDisplay::display
, _window
,
64 _style
->getBorderWidth());
66 XMoveWindow(otk::OBDisplay::display
, _client
->window(),
67 _size
.left
, _size
.top
);
69 // XXX: make everything redraw
74 void OBFrame::resize()
76 XResizeWindow(otk::OBDisplay::display
, _window
,
77 _size
.left
+ _size
.right
+ _client
->area().width(),
78 _size
.top
+ _size
.bottom
+ _client
->area().height());
79 // XXX: more is gunna have to happen here
86 if (!_client
->shaped()) {
87 // clear the shape on the frame window
88 XShapeCombineMask(otk::OBDisplay::display
, _window
, ShapeBounding
,
89 _size
.left
- 2,//frame.margin.left - frame.border_w,
90 _size
.top
- 2,//frame.margin.top - frame.border_w,
93 // make the frame's shape match the clients
94 XShapeCombineShape(otk::OBDisplay::display
, _window
, ShapeBounding
,
97 _client
->window(), ShapeBounding
, ShapeSet
);
103 if (decorations & Decor_Titlebar) {
104 xrect[0].x = xrect[0].y = -frame.border_w;
105 xrect[0].width = frame.rect.width();
106 xrect[0].height = frame.title_h + (frame.border_w * 2);
110 if (decorations & Decor_Handle) {
111 xrect[1].x = -frame.border_w;
112 xrect[1].y = frame.rect.height() - frame.margin.bottom +
113 frame.mwm_border_w - frame.border_w;
114 xrect[1].width = frame.rect.width();
115 xrect[1].height = frame.handle_h + (frame.border_w * 2);
119 XShapeCombineRectangles(otk::OBDisplay::display
, _window
,
120 ShapeBounding
, 0, 0, xrect
, num
,
121 ShapeUnion
, Unsorted
);
127 void OBFrame::grabClient()
130 XGrabServer(otk::OBDisplay::display
);
132 // select the event mask on the frame
133 XSelectInput(otk::OBDisplay::display
, _window
, SubstructureRedirectMask
);
135 // reparent the client to the frame
136 XSelectInput(otk::OBDisplay::display
, _client
->window(),
137 OBClient::event_mask
& ~StructureNotifyMask
);
138 XReparentWindow(otk::OBDisplay::display
, _client
->window(), _window
,
139 _size
.left
, _size
.top
);
140 XSelectInput(otk::OBDisplay::display
, _client
->window(),
141 OBClient::event_mask
);
143 // raise the client above the frame
144 XRaiseWindow(otk::OBDisplay::display
, _client
->window());
145 // map the client so it maps when the frame does
146 XMapWindow(otk::OBDisplay::display
, _client
->window());
148 XUngrabServer(otk::OBDisplay::display
);
155 void OBFrame::releaseClient(bool remap
)
157 // check if the app has already reparented its window to the root window
159 if (XCheckTypedWindowEvent(otk::OBDisplay::display
, _client
->window(),
160 ReparentNotify
, &ev
)) {
161 remap
= true; // XXX: why do we remap the window if they already
162 // reparented to root?
164 // according to the ICCCM - if the client doesn't reparent to
165 // root, then we have to do it for them
166 XReparentWindow(otk::OBDisplay::display
, _client
->window(),
167 _screen
->getRootWindow(),
168 _client
->area().x(), _client
->area().y());
171 // if we want to remap the window, do so now
173 XMapWindow(otk::OBDisplay::display
, _client
->window());
177 Window
OBFrame::createFrame()
179 XSetWindowAttributes attrib_create
;
180 unsigned long create_mask
= CWBackPixmap
| CWBorderPixel
| CWColormap
|
181 CWOverrideRedirect
| CWEventMask
;
183 attrib_create
.background_pixmap
= None
;
184 attrib_create
.colormap
= _screen
->getColormap();
185 attrib_create
.override_redirect
= True
;
186 attrib_create
.event_mask
= EnterWindowMask
| LeaveWindowMask
| ButtonPress
;
188 We catch button presses because other wise they get passed down to the
189 root window, which will then cause root menus to show when you click the
193 return XCreateWindow(otk::OBDisplay::display
, _screen
->getRootWindow(),
194 0, 0, 1, 1, _style
->getBorderWidth(),
195 _screen
->getDepth(), InputOutput
, _screen
->getVisual(),
196 create_mask
, &attrib_create
);