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