]> Dogcows Code - chaz/openbox/blob - src/frame.cc
position the client inside the frame correctly.
[chaz/openbox] / src / frame.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2
3 #ifdef HAVE_CONFIG_H
4 # include "../config.h"
5 #endif
6
7 #include "frame.hh"
8 #include "client.hh"
9 #include "otk/display.hh"
10
11 namespace ob {
12
13 OBFrame::OBFrame(const OBClient *client, const otk::Style *style)
14 : _client(client),
15 _screen(otk::OBDisplay::screenInfo(client->screen()))
16 {
17 assert(client);
18 assert(style);
19
20 _style = 0;
21 loadStyle(style);
22
23 _window = createFrame();
24 assert(_window);
25
26 grabClient();
27 }
28
29
30 OBFrame::~OBFrame()
31 {
32 releaseClient(false);
33 }
34
35
36 void OBFrame::loadStyle(const otk::Style *style)
37 {
38 assert(style);
39
40 // if a style was previously set, then 'replace' is true, cause we're
41 // replacing a style
42 // NOTE: if this is false, then DO NOT DO SHIT WITH _window, it doesnt exist
43 bool replace = (_style);
44
45 if (replace) {
46 // XXX: do shit here whatever
47 }
48
49 _style = style;
50
51 // XXX: load shit like this from the style!
52 _size.left = _size.top = _size.bottom = _size.right = 2;
53
54 if (replace) {
55 XSetWindowBorderWidth(otk::OBDisplay::display, _window,
56 _style->getBorderWidth());
57
58 // XXX: make everything redraw
59 }
60 }
61
62
63 void OBFrame::resize()
64 {
65 XResizeWindow(otk::OBDisplay::display, _window,
66 _size.left + _size.right + _client->area().width(),
67 _size.top + _size.bottom + _client->area().height());
68 XMoveWindow(otk::OBDisplay::display, _client->window(),
69 _size.left, _size.top);
70 // XXX: more is gunna have to happen here
71 }
72
73
74 void OBFrame::shape()
75 {
76 // XXX: if shaped, shape the frame to the client..
77 }
78
79
80 void OBFrame::grabClient()
81 {
82
83 XGrabServer(otk::OBDisplay::display);
84
85 // select the event mask on the frame
86 XSelectInput(otk::OBDisplay::display, _window, SubstructureRedirectMask);
87
88 // reparent the client to the frame
89 XSelectInput(otk::OBDisplay::display, _client->window(),
90 OBClient::event_mask & ~StructureNotifyMask);
91 XReparentWindow(otk::OBDisplay::display, _client->window(), _window, 0, 0);
92 XSelectInput(otk::OBDisplay::display, _client->window(),
93 OBClient::event_mask);
94
95 // raise the client above the frame
96 XRaiseWindow(otk::OBDisplay::display, _client->window());
97 // map the client so it maps when the frame does
98 XMapWindow(otk::OBDisplay::display, _client->window());
99
100 XUngrabServer(otk::OBDisplay::display);
101
102 resize();
103 shape();
104 }
105
106
107 void OBFrame::releaseClient(bool remap)
108 {
109 // check if the app has already reparented its window to the root window
110 XEvent ev;
111 if (XCheckTypedWindowEvent(otk::OBDisplay::display, _client->window(),
112 ReparentNotify, &ev)) {
113 remap = true; // XXX: why do we remap the window if they already
114 // reparented to root?
115 } else {
116 // according to the ICCCM - if the client doesn't reparent to
117 // root, then we have to do it for them
118 XReparentWindow(otk::OBDisplay::display, _client->window(),
119 _screen->getRootWindow(),
120 _client->area().x(), _client->area().y());
121 }
122
123 // if we want to remap the window, do so now
124 if (remap)
125 XMapWindow(otk::OBDisplay::display, _client->window());
126 }
127
128
129 Window OBFrame::createFrame()
130 {
131 XSetWindowAttributes attrib_create;
132 unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWColormap |
133 CWOverrideRedirect | CWEventMask;
134
135 attrib_create.background_pixmap = None;
136 attrib_create.colormap = _screen->getColormap();
137 attrib_create.override_redirect = True;
138 attrib_create.event_mask = EnterWindowMask | LeaveWindowMask | ButtonPress;
139 /*
140 We catch button presses because other wise they get passed down to the
141 root window, which will then cause root menus to show when you click the
142 window's frame.
143 */
144
145 return XCreateWindow(otk::OBDisplay::display, _screen->getRootWindow(),
146 0, 0, 1, 1, _style->getBorderWidth(),
147 _screen->getDepth(), InputOutput, _screen->getVisual(),
148 create_mask, &attrib_create);
149 }
150
151 }
This page took 0.042479 seconds and 5 git commands to generate.