]>
Dogcows Code - chaz/openbox/blob - src/screen.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
4 # include "../config.h"
9 #define _(str) gettext(str)
15 #include "otk/display.hh"
18 static int anotherWMRunning(Display
*display
, XErrorEvent
*) {
19 printf(_("Another window manager already running on display %s.\n"),
20 DisplayString(display
));
29 OBScreen::OBScreen(int screen
)
32 assert(screen
>= 0); assert(screen
< ScreenCount(otk::OBDisplay::display
));
33 _info
= otk::OBDisplay::screenInfo(screen
);
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
);
42 _managed
= !::running
;
43 if (! _managed
) return; // was unable to manage the screen
45 printf(_("Managing screen %d: visual 0x%lx, depth %d\n"),
46 _number
, XVisualIDFromVisual(_info
->getVisual()), _info
->getDepth());
49 Openbox::instance
->property()->set(_info
->getRootWindow(),
50 otk::OBProperty::openbox_pid
,
51 otk::OBProperty::Atom_Cardinal
,
52 (unsigned long) getpid());
55 // set the mouse cursor for the root window (the default cursor)
56 XDefineCursor(otk::OBDisplay::display
, _info
->getRootWindow(),
57 Openbox::instance
->cursors().session
);
59 _image_control
= new otk::BImageControl(Openbox::instance
->timerManager(),
61 _image_control
->installRootColormap();
62 _root_cmap_installed
= True
;
65 // Set the netwm atoms for geomtery and viewport
66 unsigned long geometry
[] = { _size
.x(),
68 Openbox::instance
->property()->set(_info
->getRootWindow(),
69 otk::OBProperty::net_desktop_geometry
,
70 otk::OBProperty::Atom_Cardinal
,
72 unsigned long viewport
[] = { 0, 0 };
73 Openbox::instance
->property()->set(_info
->getRootWindow(),
74 otk::OBProperty::net_desktop_viewport
,
75 otk::OBProperty::Atom_Cardinal
,
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
85 // XXX: "change to" the first workspace to initialize stuff
91 if (! _managed
) return;
93 delete _image_control
;
97 void OBScreen::manageExisting()
99 unsigned int i
, j
, nchild
;
100 Window r
, p
, *children
;
101 XQueryTree(otk::OBDisplay::display
, _info
->getRootWindow(), &r
, &p
,
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;
108 XWMHints
*wmhints
= XGetWMHints(otk::OBDisplay::display
,
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
) {
126 // manage shown windows
127 for (i
= 0; i
< nchild
; ++i
) {
128 if (children
[i
] == None
)
131 XWindowAttributes attrib
;
132 if (XGetWindowAttributes(otk::OBDisplay::display
, children
[i
], &attrib
)) {
133 if (attrib
.override_redirect
) continue;
135 if (attrib
.map_state
!= IsUnmapped
) {
136 // XXX: manageWindow(children[i]);
145 //! Adds a window's strut to the screen's list of reserved spaces
146 void OBScreen::addStrut(otk::Strut
*strut
)
148 _struts
.push_back(strut
);
152 //! Removes a window's strut from the screen's list of reserved spaces
153 void OBScreen::removeStrut(otk::Strut
*strut
)
155 _struts
.remove(strut
);
159 void OBScreen::calcArea()
161 otk::Rect old_area
= _area
;
165 // reset to the full areas
166 if (isXineramaActive())
167 xineramaUsableArea = getXineramaAreas();
171 /* these values represent offsets from the screen edge
172 * we look for the biggest offset on each edge and then apply them
174 * do not be confused by the similarity to the names of Rect's members
176 unsigned int current_left
= 0, current_right
= 0, current_top
= 0,
179 StrutList::const_iterator it
= _struts
.begin(), end
= _struts
.end();
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
;
193 _area
.setRect(current_left
, current_top
,
194 _info
->getWidth() - (current_left
+ current_right
),
195 _info
->getHeight() - (current_top
+ current_bottom
));
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());
207 if (xit->y() < usableArea.y()) {
208 xit->setY(usableArea.y());
209 xit->setHeight(xit->height() - usableArea.y());
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());
220 if (old_area
!= _area
)
221 // XXX: re-maximize windows
227 void OBScreen::setClientList()
231 // create an array of the window ids
232 if (_clients
.size() > 0) {
235 windows
= new Window
[_clients
.size()];
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();
242 windows
= (Window
*) 0;
244 Openbox::instance
->property()->set(_info
->getRootWindow(),
245 otk::OBProperty::net_client_list
,
246 otk::OBProperty::Atom_Window
,
247 windows
, _clients
.size());
256 void OBScreen::setStackingList()
258 // The below comment is wrong now hopefully :> but ill keep it here for
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.
266 Openbox::instance->property()->set(_info->getRootWindow(),
267 otk::OBProperty::net_client_list_stacking,
268 otk::OBProperty::Atom_Window,
269 _stacking, _stacking.size());
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
,
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();
292 xatom->set(getRootWindow(), otk::OBProperty::net_workarea,
293 otk::OBProperty::Atom_Cardinal,
294 dims, 4 * workspacesList.size());
297 xatom->set(getRootWindow(), otk::OBProperty::net_workarea,
298 otk::OBProperty::Atom_Cardinal, 0, 0);
This page took 0.055736 seconds and 5 git commands to generate.