]> Dogcows Code - chaz/openbox/blob - src/screen.cc
adding the new OBScreen class actually!
[chaz/openbox] / src / screen.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 extern "C" {
8 #include "gettext.h"
9 #define _(str) gettext(str)
10 }
11
12 #include "screen.hh"
13 #include "client.hh"
14 #include "openbox.hh"
15 #include "otk/display.hh"
16
17 static bool running;
18 static int anotherWMRunning(Display *display, XErrorEvent *) {
19 printf(_("Another window manager already running on display %s.\n"),
20 DisplayString(display));
21 running = true;
22 return -1;
23 }
24
25
26 namespace ob {
27
28
29 OBScreen::OBScreen(int screen)
30 : _number(screen)
31 {
32 assert(screen >= 0); assert(screen < ScreenCount(otk::OBDisplay::display));
33 _info = otk::OBDisplay::screenInfo(screen);
34
35 ::running = false;
36 XErrorHandler old = XSetErrorHandler(::anotherWMRunning);
37 XSelectInput(otk::OBDisplay::display, _info->getRootWindow(),
38 OBScreen::event_mask);
39 XSync(otk::OBDisplay::display, false);
40 XSetErrorHandler(old);
41
42 _managed = !::running;
43 if (! _managed) return; // was unable to manage the screen
44
45 printf(_("Managing screen %d: visual 0x%lx, depth %d\n"),
46 _number, XVisualIDFromVisual(_info->getVisual()), _info->getDepth());
47
48 #ifdef HAVE_GETPID
49 Openbox::instance->property()->set(_info->getRootWindow(),
50 otk::OBProperty::openbox_pid,
51 otk::OBProperty::Atom_Cardinal,
52 (unsigned long) getpid());
53 #endif // HAVE_GETPID
54
55 // set the mouse cursor for the root window (the default cursor)
56 XDefineCursor(otk::OBDisplay::display, _info->getRootWindow(),
57 Openbox::instance->cursors().session);
58
59 _image_control = new otk::BImageControl(Openbox::instance->timerManager(),
60 _info, true);
61 _image_control->installRootColormap();
62 _root_cmap_installed = True;
63
64
65 // Set the netwm atoms for geomtery and viewport
66 unsigned long geometry[] = { _size.x(),
67 _size.y() };
68 Openbox::instance->property()->set(_info->getRootWindow(),
69 otk::OBProperty::net_desktop_geometry,
70 otk::OBProperty::Atom_Cardinal,
71 geometry, 2);
72 unsigned long viewport[] = { 0, 0 };
73 Openbox::instance->property()->set(_info->getRootWindow(),
74 otk::OBProperty::net_desktop_viewport,
75 otk::OBProperty::Atom_Cardinal,
76 viewport, 2);
77
78 // these may be further updated if any pre-existing windows are found in
79 // the manageExising() function
80 setClientList(); // initialize the client lists, which will be empty
81 calcArea(); // initialize the available working area
82
83 manageExisting();
84
85 // XXX: "change to" the first workspace to initialize stuff
86 }
87
88
89 OBScreen::~OBScreen()
90 {
91 if (! _managed) return;
92
93 delete _image_control;
94 }
95
96
97 void OBScreen::manageExisting()
98 {
99 unsigned int i, j, nchild;
100 Window r, p, *children;
101 XQueryTree(otk::OBDisplay::display, _info->getRootWindow(), &r, &p,
102 &children, &nchild);
103
104 // preen the window list of all icon windows... for better dockapp support
105 for (i = 0; i < nchild; i++) {
106 if (children[i] == None) continue;
107
108 XWMHints *wmhints = XGetWMHints(otk::OBDisplay::display,
109 children[i]);
110
111 if (wmhints) {
112 if ((wmhints->flags & IconWindowHint) &&
113 (wmhints->icon_window != children[i])) {
114 for (j = 0; j < nchild; j++) {
115 if (children[j] == wmhints->icon_window) {
116 children[j] = None;
117 break;
118 }
119 }
120 }
121
122 XFree(wmhints);
123 }
124 }
125
126 // manage shown windows
127 for (i = 0; i < nchild; ++i) {
128 if (children[i] == None)
129 continue;
130
131 XWindowAttributes attrib;
132 if (XGetWindowAttributes(otk::OBDisplay::display, children[i], &attrib)) {
133 if (attrib.override_redirect) continue;
134
135 if (attrib.map_state != IsUnmapped) {
136 // XXX: manageWindow(children[i]);
137 }
138 }
139 }
140
141 XFree(children);
142 }
143
144
145 //! Adds a window's strut to the screen's list of reserved spaces
146 void OBScreen::addStrut(otk::Strut *strut)
147 {
148 _struts.push_back(strut);
149 }
150
151
152 //! Removes a window's strut from the screen's list of reserved spaces
153 void OBScreen::removeStrut(otk::Strut *strut)
154 {
155 _struts.remove(strut);
156 }
157
158
159 void OBScreen::calcArea()
160 {
161 otk::Rect old_area = _area;
162
163 /*
164 #ifdef XINERAMA
165 // reset to the full areas
166 if (isXineramaActive())
167 xineramaUsableArea = getXineramaAreas();
168 #endif // XINERAMA
169 */
170
171 /* these values represent offsets from the screen edge
172 * we look for the biggest offset on each edge and then apply them
173 * all at once
174 * do not be confused by the similarity to the names of Rect's members
175 */
176 unsigned int current_left = 0, current_right = 0, current_top = 0,
177 current_bottom = 0;
178
179 StrutList::const_iterator it = _struts.begin(), end = _struts.end();
180
181 for(; it != end; ++it) {
182 otk::Strut *strut = *it;
183 if (strut->left > current_left)
184 current_left = strut->left;
185 if (strut->top > current_top)
186 current_top = strut->top;
187 if (strut->right > current_right)
188 current_right = strut->right;
189 if (strut->bottom > current_bottom)
190 current_bottom = strut->bottom;
191 }
192
193 _area.setRect(current_left, current_top,
194 _info->getWidth() - (current_left + current_right),
195 _info->getHeight() - (current_top + current_bottom));
196
197 /*
198 #ifdef XINERAMA
199 if (isXineramaActive()) {
200 // keep each of the ximerama-defined areas inside the strut
201 RectList::iterator xit, xend = xineramaUsableArea.end();
202 for (xit = xineramaUsableArea.begin(); xit != xend; ++xit) {
203 if (xit->x() < usableArea.x()) {
204 xit->setX(usableArea.x());
205 xit->setWidth(xit->width() - usableArea.x());
206 }
207 if (xit->y() < usableArea.y()) {
208 xit->setY(usableArea.y());
209 xit->setHeight(xit->height() - usableArea.y());
210 }
211 if (xit->x() + xit->width() > usableArea.width())
212 xit->setWidth(usableArea.width() - xit->x());
213 if (xit->y() + xit->height() > usableArea.height())
214 xit->setHeight(usableArea.height() - xit->y());
215 }
216 }
217 #endif // XINERAMA
218 */
219
220 if (old_area != _area)
221 // XXX: re-maximize windows
222
223 setWorkArea();
224 }
225
226
227 void OBScreen::setClientList()
228 {
229 Window *windows;
230
231 // create an array of the window ids
232 if (_clients.size() > 0) {
233 Window *win_it;
234
235 windows = new Window[_clients.size()];
236 win_it = windows;
237 ClientList::const_iterator it = _clients.begin();
238 const ClientList::const_iterator end = _clients.end();
239 for (; it != end; ++it, ++win_it)
240 *win_it = (*it)->window();
241 } else
242 windows = (Window*) 0;
243
244 Openbox::instance->property()->set(_info->getRootWindow(),
245 otk::OBProperty::net_client_list,
246 otk::OBProperty::Atom_Window,
247 windows, _clients.size());
248
249 if (_clients.size())
250 delete [] windows;
251
252 setStackingList();
253 }
254
255
256 void OBScreen::setStackingList()
257 {
258 // The below comment is wrong now hopefully :> but ill keep it here for
259 // reference anyways
260 /*
261 Get the stacking order from all of the workspaces.
262 We start with the current workspace so that the sticky windows will be
263 in the right order on the current workspace.
264 */
265 /*
266 Openbox::instance->property()->set(_info->getRootWindow(),
267 otk::OBProperty::net_client_list_stacking,
268 otk::OBProperty::Atom_Window,
269 _stacking, _stacking.size());
270 */
271 }
272
273
274 void OBScreen::setWorkArea() {
275 unsigned long area[] = { _area.x(), _area.y(),
276 _area.width(), _area.height() };
277 Openbox::instance->property()->set(_info->getRootWindow(),
278 otk::OBProperty::net_workarea,
279 otk::OBProperty::Atom_Cardinal,
280 area, 4);
281 /*
282 if (workspacesList.size() > 0) {
283 unsigned long *dims = new unsigned long[4 * workspacesList.size()];
284 for (unsigned int i = 0, m = workspacesList.size(); i < m; ++i) {
285 // XXX: this could be different for each workspace
286 const otk::Rect &area = availableArea();
287 dims[(i * 4) + 0] = area.x();
288 dims[(i * 4) + 1] = area.y();
289 dims[(i * 4) + 2] = area.width();
290 dims[(i * 4) + 3] = area.height();
291 }
292 xatom->set(getRootWindow(), otk::OBProperty::net_workarea,
293 otk::OBProperty::Atom_Cardinal,
294 dims, 4 * workspacesList.size());
295 delete [] dims;
296 } else
297 xatom->set(getRootWindow(), otk::OBProperty::net_workarea,
298 otk::OBProperty::Atom_Cardinal, 0, 0);
299 */
300 }
301
302
303 }
This page took 0.046254 seconds and 5 git commands to generate.