]>
Dogcows Code - chaz/openbox/blob - src/screen.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
4 # include "../config.h"
10 #endif // HAVE_STDIO_H
13 #define _(str) gettext(str)
19 #include "otk/display.hh"
22 static int anotherWMRunning(Display
*display
, XErrorEvent
*) {
23 printf(_("Another window manager already running on display %s.\n"),
24 DisplayString(display
));
33 OBScreen::OBScreen(int screen
)
36 assert(screen
>= 0); assert(screen
< ScreenCount(otk::OBDisplay::display
));
37 _info
= otk::OBDisplay::screenInfo(screen
);
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
);
46 _managed
= !::running
;
47 if (! _managed
) return; // was unable to manage the screen
49 printf(_("Managing screen %d: visual 0x%lx, depth %d\n"),
50 _number
, XVisualIDFromVisual(_info
->getVisual()), _info
->getDepth());
53 Openbox::instance
->property()->set(_info
->getRootWindow(),
54 otk::OBProperty::openbox_pid
,
55 otk::OBProperty::Atom_Cardinal
,
56 (unsigned long) getpid());
59 // set the mouse cursor for the root window (the default cursor)
60 XDefineCursor(otk::OBDisplay::display
, _info
->getRootWindow(),
61 Openbox::instance
->cursors().session
);
63 _image_control
= new otk::BImageControl(Openbox::instance
->timerManager(),
65 _image_control
->installRootColormap();
66 _root_cmap_installed
= True
;
69 // Set the netwm atoms for geomtery and viewport
70 unsigned long geometry
[] = { _size
.x(),
72 Openbox::instance
->property()->set(_info
->getRootWindow(),
73 otk::OBProperty::net_desktop_geometry
,
74 otk::OBProperty::Atom_Cardinal
,
76 unsigned long viewport
[] = { 0, 0 };
77 Openbox::instance
->property()->set(_info
->getRootWindow(),
78 otk::OBProperty::net_desktop_viewport
,
79 otk::OBProperty::Atom_Cardinal
,
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
89 // XXX: "change to" the first workspace to initialize stuff
95 if (! _managed
) return;
97 delete _image_control
;
101 void OBScreen::manageExisting()
103 unsigned int i
, j
, nchild
;
104 Window r
, p
, *children
;
105 XQueryTree(otk::OBDisplay::display
, _info
->getRootWindow(), &r
, &p
,
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;
112 XWMHints
*wmhints
= XGetWMHints(otk::OBDisplay::display
,
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
) {
130 // manage shown windows
131 for (i
= 0; i
< nchild
; ++i
) {
132 if (children
[i
] == None
)
135 XWindowAttributes attrib
;
136 if (XGetWindowAttributes(otk::OBDisplay::display
, children
[i
], &attrib
)) {
137 if (attrib
.override_redirect
) continue;
139 if (attrib
.map_state
!= IsUnmapped
) {
140 // XXX: manageWindow(children[i]);
149 //! Adds a window's strut to the screen's list of reserved spaces
150 void OBScreen::addStrut(otk::Strut
*strut
)
152 _struts
.push_back(strut
);
156 //! Removes a window's strut from the screen's list of reserved spaces
157 void OBScreen::removeStrut(otk::Strut
*strut
)
159 _struts
.remove(strut
);
163 void OBScreen::calcArea()
165 otk::Rect old_area
= _area
;
169 // reset to the full areas
170 if (isXineramaActive())
171 xineramaUsableArea = getXineramaAreas();
175 /* these values represent offsets from the screen edge
176 * we look for the biggest offset on each edge and then apply them
178 * do not be confused by the similarity to the names of Rect's members
180 unsigned int current_left
= 0, current_right
= 0, current_top
= 0,
183 StrutList::const_iterator it
= _struts
.begin(), end
= _struts
.end();
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
;
197 _area
.setRect(current_left
, current_top
,
198 _info
->getWidth() - (current_left
+ current_right
),
199 _info
->getHeight() - (current_top
+ current_bottom
));
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());
211 if (xit->y() < usableArea.y()) {
212 xit->setY(usableArea.y());
213 xit->setHeight(xit->height() - usableArea.y());
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());
224 if (old_area
!= _area
)
225 // XXX: re-maximize windows
231 void OBScreen::setClientList()
235 // create an array of the window ids
236 if (_clients
.size() > 0) {
239 windows
= new Window
[_clients
.size()];
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();
246 windows
= (Window
*) 0;
248 Openbox::instance
->property()->set(_info
->getRootWindow(),
249 otk::OBProperty::net_client_list
,
250 otk::OBProperty::Atom_Window
,
251 windows
, _clients
.size());
260 void OBScreen::setStackingList()
262 // The below comment is wrong now hopefully :> but ill keep it here for
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.
270 Openbox::instance->property()->set(_info->getRootWindow(),
271 otk::OBProperty::net_client_list_stacking,
272 otk::OBProperty::Atom_Window,
273 _stacking, _stacking.size());
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
,
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();
296 xatom->set(getRootWindow(), otk::OBProperty::net_workarea,
297 otk::OBProperty::Atom_Cardinal,
298 dims, 4 * workspacesList.size());
301 xatom->set(getRootWindow(), otk::OBProperty::net_workarea,
302 otk::OBProperty::Atom_Cardinal, 0, 0);
This page took 0.04982 seconds and 5 git commands to generate.