]>
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 # include <sys/types.h>
15 #endif // HAVE_UNISTD_H
18 #define _(str) gettext(str)
24 #include "otk/display.hh"
27 static int anotherWMRunning(Display
*display
, XErrorEvent
*) {
28 printf(_("Another window manager already running on display %s.\n"),
29 DisplayString(display
));
38 OBScreen::OBScreen(int screen
)
41 assert(screen
>= 0); assert(screen
< ScreenCount(otk::OBDisplay::display
));
42 _info
= otk::OBDisplay::screenInfo(screen
);
45 XErrorHandler old
= XSetErrorHandler(::anotherWMRunning
);
46 XSelectInput(otk::OBDisplay::display
, _info
->getRootWindow(),
47 OBScreen::event_mask
);
48 XSync(otk::OBDisplay::display
, false);
49 XSetErrorHandler(old
);
51 _managed
= !::running
;
52 if (! _managed
) return; // was unable to manage the screen
54 printf(_("Managing screen %d: visual 0x%lx, depth %d\n"),
55 _number
, XVisualIDFromVisual(_info
->getVisual()), _info
->getDepth());
57 Openbox::instance
->property()->set(_info
->getRootWindow(),
58 otk::OBProperty::openbox_pid
,
59 otk::OBProperty::Atom_Cardinal
,
60 (unsigned long) getpid());
62 // set the mouse cursor for the root window (the default cursor)
63 XDefineCursor(otk::OBDisplay::display
, _info
->getRootWindow(),
64 Openbox::instance
->cursors().session
);
66 _image_control
= new otk::BImageControl(Openbox::instance
->timerManager(),
68 _image_control
->installRootColormap();
69 _root_cmap_installed
= True
;
71 _style
.setImageControl(_image_control
);
74 // Set the netwm atoms for geomtery and viewport
75 unsigned long geometry
[] = { _size
.x(),
77 Openbox::instance
->property()->set(_info
->getRootWindow(),
78 otk::OBProperty::net_desktop_geometry
,
79 otk::OBProperty::Atom_Cardinal
,
81 unsigned long viewport
[] = { 0, 0 };
82 Openbox::instance
->property()->set(_info
->getRootWindow(),
83 otk::OBProperty::net_desktop_viewport
,
84 otk::OBProperty::Atom_Cardinal
,
87 // these may be further updated if any pre-existing windows are found in
88 // the manageExising() function
89 setClientList(); // initialize the client lists, which will be empty
90 calcArea(); // initialize the available working area
94 // XXX: "change to" the first workspace to initialize stuff
100 if (! _managed
) return;
102 delete _image_control
;
106 void OBScreen::manageExisting()
108 unsigned int i
, j
, nchild
;
109 Window r
, p
, *children
;
110 XQueryTree(otk::OBDisplay::display
, _info
->getRootWindow(), &r
, &p
,
113 // preen the window list of all icon windows... for better dockapp support
114 for (i
= 0; i
< nchild
; i
++) {
115 if (children
[i
] == None
) continue;
117 XWMHints
*wmhints
= XGetWMHints(otk::OBDisplay::display
,
121 if ((wmhints
->flags
& IconWindowHint
) &&
122 (wmhints
->icon_window
!= children
[i
])) {
123 for (j
= 0; j
< nchild
; j
++) {
124 if (children
[j
] == wmhints
->icon_window
) {
135 // manage shown windows
136 for (i
= 0; i
< nchild
; ++i
) {
137 if (children
[i
] == None
)
140 XWindowAttributes attrib
;
141 if (XGetWindowAttributes(otk::OBDisplay::display
, children
[i
], &attrib
)) {
142 if (attrib
.override_redirect
) continue;
144 if (attrib
.map_state
!= IsUnmapped
) {
145 // XXX: manageWindow(children[i]);
154 //! Adds a window's strut to the screen's list of reserved spaces
155 void OBScreen::addStrut(otk::Strut
*strut
)
157 _struts
.push_back(strut
);
161 //! Removes a window's strut from the screen's list of reserved spaces
162 void OBScreen::removeStrut(otk::Strut
*strut
)
164 _struts
.remove(strut
);
168 void OBScreen::calcArea()
170 otk::Rect old_area
= _area
;
174 // reset to the full areas
175 if (isXineramaActive())
176 xineramaUsableArea = getXineramaAreas();
180 /* these values represent offsets from the screen edge
181 * we look for the biggest offset on each edge and then apply them
183 * do not be confused by the similarity to the names of Rect's members
185 unsigned int current_left
= 0, current_right
= 0, current_top
= 0,
188 StrutList::const_iterator it
= _struts
.begin(), end
= _struts
.end();
190 for(; it
!= end
; ++it
) {
191 otk::Strut
*strut
= *it
;
192 if (strut
->left
> current_left
)
193 current_left
= strut
->left
;
194 if (strut
->top
> current_top
)
195 current_top
= strut
->top
;
196 if (strut
->right
> current_right
)
197 current_right
= strut
->right
;
198 if (strut
->bottom
> current_bottom
)
199 current_bottom
= strut
->bottom
;
202 _area
.setRect(current_left
, current_top
,
203 _info
->getWidth() - (current_left
+ current_right
),
204 _info
->getHeight() - (current_top
+ current_bottom
));
208 if (isXineramaActive()) {
209 // keep each of the ximerama-defined areas inside the strut
210 RectList::iterator xit, xend = xineramaUsableArea.end();
211 for (xit = xineramaUsableArea.begin(); xit != xend; ++xit) {
212 if (xit->x() < usableArea.x()) {
213 xit->setX(usableArea.x());
214 xit->setWidth(xit->width() - usableArea.x());
216 if (xit->y() < usableArea.y()) {
217 xit->setY(usableArea.y());
218 xit->setHeight(xit->height() - usableArea.y());
220 if (xit->x() + xit->width() > usableArea.width())
221 xit->setWidth(usableArea.width() - xit->x());
222 if (xit->y() + xit->height() > usableArea.height())
223 xit->setHeight(usableArea.height() - xit->y());
229 if (old_area
!= _area
)
230 // XXX: re-maximize windows
236 void OBScreen::setClientList()
240 // create an array of the window ids
241 if (_clients
.size() > 0) {
244 windows
= new Window
[_clients
.size()];
246 ClientList::const_iterator it
= _clients
.begin();
247 const ClientList::const_iterator end
= _clients
.end();
248 for (; it
!= end
; ++it
, ++win_it
)
249 *win_it
= (*it
)->window();
251 windows
= (Window
*) 0;
253 Openbox::instance
->property()->set(_info
->getRootWindow(),
254 otk::OBProperty::net_client_list
,
255 otk::OBProperty::Atom_Window
,
256 windows
, _clients
.size());
265 void OBScreen::setStackingList()
267 // The below comment is wrong now hopefully :> but ill keep it here for
270 Get the stacking order from all of the workspaces.
271 We start with the current workspace so that the sticky windows will be
272 in the right order on the current workspace.
275 Openbox::instance->property()->set(_info->getRootWindow(),
276 otk::OBProperty::net_client_list_stacking,
277 otk::OBProperty::Atom_Window,
278 _stacking, _stacking.size());
283 void OBScreen::setWorkArea() {
284 unsigned long area
[] = { _area
.x(), _area
.y(),
285 _area
.width(), _area
.height() };
286 Openbox::instance
->property()->set(_info
->getRootWindow(),
287 otk::OBProperty::net_workarea
,
288 otk::OBProperty::Atom_Cardinal
,
291 if (workspacesList.size() > 0) {
292 unsigned long *dims = new unsigned long[4 * workspacesList.size()];
293 for (unsigned int i = 0, m = workspacesList.size(); i < m; ++i) {
294 // XXX: this could be different for each workspace
295 const otk::Rect &area = availableArea();
296 dims[(i * 4) + 0] = area.x();
297 dims[(i * 4) + 1] = area.y();
298 dims[(i * 4) + 2] = area.width();
299 dims[(i * 4) + 3] = area.height();
301 xatom->set(getRootWindow(), otk::OBProperty::net_workarea,
302 otk::OBProperty::Atom_Cardinal,
303 dims, 4 * workspacesList.size());
306 xatom->set(getRootWindow(), otk::OBProperty::net_workarea,
307 otk::OBProperty::Atom_Cardinal, 0, 0);
312 void OBScreen::loadStyle(const otk::Configuration
&config
)
315 if (Openbox::instance
->state() == Openbox::State_Starting
)
318 // XXX: make stuff redraw!
This page took 0.047979 seconds and 5 git commands to generate.