#include <screen.hh>
Inheritance diagram for ob::Screen:
Definition at line 32 of file screen.hh.
Public Types | |
typedef std::list< otk::Strut * > | StrutList |
Holds a list of otk::Strut objects. | |
typedef std::list< Client * > | ClientList |
Holds a list of Clients. | |
Public Methods | |
Screen (int screen) | |
Constructs a new Screen object. | |
virtual | ~Screen () |
Destroys the Screen object. | |
int | number () const |
bool | managed () const |
Returns if the screen was successfully managed. | |
const otk::Rect & | area () const |
Returns the area of the screen not reserved by applications' Struts. | |
const otk::RenderStyle * | style () const |
Returns the style in use on the screen. | |
Window | focuswindow () const |
An offscreen window which gets focus when nothing else has it. | |
long | desktop () const |
Returns the desktop being displayed. | |
long | numDesktops () const |
Returns the number of desktops. | |
void | updateStrut () |
Update's the screen's combined strut of all the clients. | |
void | manageExisting () |
Manage any pre-existing windows on the screen. | |
void | manageWindow (Window window) |
Manage a client window. | |
void | unmanageWindow (Client *client) |
Unmanage a client. | |
void | raiseWindow (Client *client) |
Raises a client window above all others in its stacking layer. | |
void | lowerWindow (Client *client) |
Lowers a client window below all others in its stacking layer. | |
void | setDesktopName (long i, const otk::ustring &name) |
Sets the name of a desktop by changing the root window property. | |
void | installColormap (bool install) const |
virtual void | propertyHandler (const XPropertyEvent &e) |
Called when a property of a window changes. | |
virtual void | clientMessageHandler (const XClientMessageEvent &e) |
Called when a client calls XSendEvent. | |
virtual void | mapRequestHandler (const XMapRequestEvent &e) |
Called when a different client tries to map a window. | |
Public Attributes | |
ClientList | clients |
All managed clients on the screen (in order of being mapped). | |
Static Public Attributes | |
const unsigned long | event_mask |
Private Methods | |
void | calcArea () |
Calculate the Screen::_area member. | |
void | changeSupportedAtoms () |
Set the list of supported NETWM atoms on the root window. | |
void | changeClientList () |
Set the client list on the root window. | |
void | changeStackingList () |
Set the client stacking list on the root window. | |
void | changeWorkArea () |
Set the work area hint on the root window. | |
void | updateDesktopNames () |
Get desktop names from the root window property. | |
void | changeDesktop (long desktop) |
Changes to the specified desktop, displaying windows on it and hiding windows on the others. | |
void | changeNumDesktops (long num) |
Changes the number of desktops. | |
Private Attributes | |
bool | _managed |
Was Openbox able to manage the screen? | |
int | _number |
The number of the screen on the X server. | |
const otk::ScreenInfo * | _info |
Information about this screen. | |
otk::RenderStyle | _style |
The style with which to render on the screen. | |
bool | _root_cmap_installed |
Is the root colormap currently installed? | |
otk::Rect | _area |
Area usable for placement etc (total - struts). | |
otk::Strut | _strut |
Combined strut from all of the clients' struts. | |
Window | _focuswindow |
An offscreen window which gets focus when nothing else has it. | |
Window | _supportwindow |
An offscreen window which shows that a NETWM compliant window manager is running. | |
ClientList | _stacking |
A list of all managed clients on the screen, in their stacking order. | |
long | _desktop |
The desktop currently being displayed. | |
long | _num_desktops |
The number of desktops. | |
otk::Property::StringVect | _desktop_names |
The names of all desktops. |
|
Holds a list of Clients.
|
|
Holds a list of otk::Strut objects.
|
|
Constructs a new Screen object.
Definition at line 49 of file screen.cc. References _, _desktop, _focuswindow, _info, _managed, _num_desktops, _style, otk::Property::atoms, ob::Openbox::bindings(), calcArea(), changeClientList(), changeDesktop(), changeNumDesktops(), changeSupportedAtoms(), ob::Openbox::cursors(), otk::ScreenInfo::depth(), ob::Bindings::fireEvent(), otk::ScreenInfo::height(), ob::openbox, ob::python_get_long(), ob::python_get_stringlist(), otk::EventDispatcher::registerHandler(), otk::RenderStyle::rootColor(), otk::ScreenInfo::rootWindow(), ob::Cursors::session, otk::Property::set(), otk::Property::utf8, otk::ScreenInfo::visual(), and otk::ScreenInfo::width().
00050 : WidgetBase(WidgetBase::Type_Root), 00051 _number(screen), 00052 _style(screen, "") 00053 { 00054 assert(screen >= 0); assert(screen < ScreenCount(**otk::display)); 00055 _info = otk::display->screenInfo(screen); 00056 00057 ::running = false; 00058 XErrorHandler old = XSetErrorHandler(::anotherWMRunning); 00059 XSelectInput(**otk::display, _info->rootWindow(), 00060 Screen::event_mask); 00061 XSync(**otk::display, false); 00062 XSetErrorHandler(old); 00063 00064 _managed = !::running; 00065 if (! _managed) return; // was unable to manage the screen 00066 00067 printf(_("Managing screen %d: visual 0x%lx, depth %d\n"), 00068 _number, XVisualIDFromVisual(_info->visual()), _info->depth()); 00069 00070 otk::Property::set(_info->rootWindow(), otk::Property::atoms.openbox_pid, 00071 otk::Property::atoms.cardinal, (unsigned long) getpid()); 00072 00073 // set the mouse cursor for the root window (the default cursor) 00074 XDefineCursor(**otk::display, _info->rootWindow(), 00075 openbox->cursors().session); 00076 00077 // XXX: initialize the screen's style 00078 /* 00079 otk::ustring stylepath; 00080 python_get_string("THEME", &stylepath); 00081 otk::Configuration sconfig(false); 00082 sconfig.setFile(otk::expandTilde(stylepath.c_str())); 00083 if (!sconfig.load()) { 00084 sconfig.setFile(otk::expandTilde(DEFAULTSTYLE)); 00085 if (!sconfig.load()) { 00086 printf(_("Unable to load default style: %s. Aborting.\n"), DEFAULTSTYLE); 00087 ::exit(1); 00088 } 00089 } 00090 _style.load(sconfig); 00091 */ 00092 otk::display->renderControl(_number)->drawRoot(*_style.rootColor()); 00093 00094 // set up notification of netwm support 00095 changeSupportedAtoms(); 00096 00097 // Set the netwm properties for geometry 00098 unsigned long geometry[] = { _info->width(), 00099 _info->height() }; 00100 otk::Property::set(_info->rootWindow(), 00101 otk::Property::atoms.net_desktop_geometry, 00102 otk::Property::atoms.cardinal, geometry, 2); 00103 00104 // Set the net_desktop_names property 00105 std::vector<otk::ustring> names; 00106 python_get_stringlist("DESKTOP_NAMES", &names); 00107 otk::Property::set(_info->rootWindow(), 00108 otk::Property::atoms.net_desktop_names, 00109 otk::Property::utf8, names); 00110 // the above set() will cause the updateDesktopNames to fire right away so 00111 // we have a list of desktop names 00112 00113 _desktop = 0; 00114 00115 if (!python_get_long("NUMBER_OF_DESKTOPS", &_num_desktops)) 00116 _num_desktops = 1; 00117 changeNumDesktops(_num_desktops); // set the hint 00118 00119 changeDesktop(0); // set the hint 00120 00121 // create the window which gets focus when no clients get it 00122 XSetWindowAttributes attr; 00123 attr.override_redirect = true; 00124 _focuswindow = XCreateWindow(**otk::display, _info->rootWindow(), 00125 -100, -100, 1, 1, 0, 0, InputOnly, 00126 _info->visual(), CWOverrideRedirect, &attr); 00127 XMapRaised(**otk::display, _focuswindow); 00128 00129 // these may be further updated if any pre-existing windows are found in 00130 // the manageExising() function 00131 changeClientList(); // initialize the client lists, which will be empty 00132 calcArea(); // initialize the available working area 00133 00134 // register this class as the event handler for the root window 00135 openbox->registerHandler(_info->rootWindow(), this); 00136 00137 // call the python Startup callbacks 00138 EventData data(_number, 0, EventAction::Startup, 0); 00139 openbox->bindings()->fireEvent(&data); 00140 } |
|
Destroys the Screen object.
Definition at line 143 of file screen.cc. References _info, _managed, ob::Openbox::bindings(), clients, ob::Bindings::fireEvent(), ob::openbox, otk::ScreenInfo::rootWindow(), and unmanageWindow().
00144 { 00145 if (! _managed) return; 00146 00147 XSelectInput(**otk::display, _info->rootWindow(), NoEventMask); 00148 00149 // unmanage all windows 00150 while (!clients.empty()) 00151 unmanageWindow(clients.front()); 00152 00153 // call the python Shutdown callbacks 00154 EventData data(_number, 0, EventAction::Shutdown, 0); 00155 openbox->bindings()->fireEvent(&data); 00156 00157 XDestroyWindow(**otk::display, _focuswindow); 00158 XDestroyWindow(**otk::display, _supportwindow); 00159 } |
|
Returns the area of the screen not reserved by applications' Struts.
Definition at line 148 of file screen.hh. Referenced by ob::Client::fullscreen(), and ob::Client::maximize().
00148 { return _area; } |
|
Calculate the Screen::_area member.
Definition at line 226 of file screen.cc. References _area, _info, _strut, otk::Strut::bottom, changeWorkArea(), clients, otk::ScreenInfo::height(), otk::Strut::left, otk::Strut::right, otk::Rect::setRect(), otk::Strut::top, and otk::ScreenInfo::width(). Referenced by Screen(), and updateStrut().
00227 { 00228 otk::Rect old_area = _area; 00229 00230 /* 00231 #ifdef XINERAMA 00232 // reset to the full areas 00233 if (isXineramaActive()) 00234 xineramaUsableArea = getXineramaAreas(); 00235 #endif // XINERAMA 00236 */ 00237 00238 _area.setRect(_strut.left, _strut.top, 00239 _info->width() - (_strut.left + _strut.right), 00240 _info->height() - (_strut.top + _strut.bottom)); 00241 00242 /* 00243 #ifdef XINERAMA 00244 if (isXineramaActive()) { 00245 // keep each of the ximerama-defined areas inside the strut 00246 RectList::iterator xit, xend = xineramaUsableArea.end(); 00247 for (xit = xineramaUsableArea.begin(); xit != xend; ++xit) { 00248 if (xit->x() < usableArea.x()) { 00249 xit->setX(usableArea.x()); 00250 xit->setWidth(xit->width() - usableArea.x()); 00251 } 00252 if (xit->y() < usableArea.y()) { 00253 xit->setY(usableArea.y()); 00254 xit->setHeight(xit->height() - usableArea.y()); 00255 } 00256 if (xit->x() + xit->width() > usableArea.width()) 00257 xit->setWidth(usableArea.width() - xit->x()); 00258 if (xit->y() + xit->height() > usableArea.height()) 00259 xit->setHeight(usableArea.height() - xit->y()); 00260 } 00261 } 00262 #endif // XINERAMA 00263 */ 00264 00265 if (old_area != _area) { 00266 // the area has changed, adjust all the maximized windows 00267 ClientList::iterator it, end = clients.end(); 00268 for (it = clients.begin(); it != end; ++it) 00269 (*it)->remaximize(); 00270 } 00271 00272 changeWorkArea(); 00273 } |
|
Set the client list on the root window.
Sets the _NET_CLIENT_LIST root window property. Definition at line 363 of file screen.cc. References _info, otk::Property::atoms, changeStackingList(), clients, otk::ScreenInfo::rootWindow(), and otk::Property::set(). Referenced by manageWindow(), Screen(), and unmanageWindow().
00364 { 00365 Window *windows; 00366 unsigned int size = clients.size(); 00367 00368 // create an array of the window ids 00369 if (size > 0) { 00370 Window *win_it; 00371 00372 windows = new Window[size]; 00373 win_it = windows; 00374 ClientList::const_iterator it = clients.begin(); 00375 const ClientList::const_iterator end = clients.end(); 00376 for (; it != end; ++it, ++win_it) 00377 *win_it = (*it)->window(); 00378 } else 00379 windows = (Window*) 0; 00380 00381 otk::Property::set(_info->rootWindow(), otk::Property::atoms.net_client_list, 00382 otk::Property::atoms.window, windows, size); 00383 00384 if (size) 00385 delete [] windows; 00386 00387 changeStackingList(); 00388 } |
|
Changes to the specified desktop, displaying windows on it and hiding windows on the others.
Definition at line 704 of file screen.cc. References _desktop, _info, _num_desktops, otk::Property::atoms, clients, ob::Openbox::focusedClient(), ob::openbox, otk::ScreenInfo::rootWindow(), otk::Property::set(), and ob::Openbox::setFocusedClient(). Referenced by changeNumDesktops(), clientMessageHandler(), and Screen().
00705 { 00706 if (!(desktop >= 0 && desktop < _num_desktops)) return; 00707 00708 printf("Moving to desktop %ld\n", desktop); 00709 00710 long old = _desktop; 00711 00712 _desktop = desktop; 00713 otk::Property::set(_info->rootWindow(), 00714 otk::Property::atoms.net_current_desktop, 00715 otk::Property::atoms.cardinal, _desktop); 00716 00717 if (old == _desktop) return; 00718 00719 ClientList::iterator it, end = clients.end(); 00720 for (it = clients.begin(); it != end; ++it) { 00721 if ((*it)->desktop() == old) { 00722 (*it)->frame->hide(); 00723 } else if ((*it)->desktop() == _desktop) { 00724 (*it)->frame->show(); 00725 } 00726 } 00727 00728 // force the callbacks to fire 00729 if (!openbox->focusedClient()) 00730 openbox->setFocusedClient(0); 00731 } |
|
Changes the number of desktops.
Definition at line 733 of file screen.cc. References _desktop, _info, _num_desktops, otk::Property::atoms, changeDesktop(), changeWorkArea(), clients, otk::ScreenInfo::rootWindow(), and otk::Property::set(). Referenced by clientMessageHandler(), and Screen().
00734 { 00735 assert(num > 0); 00736 00737 if (!(num > 0)) return; 00738 00739 // move windows on desktops that will no longer exist! 00740 ClientList::iterator it, end = clients.end(); 00741 for (it = clients.begin(); it != end; ++it) { 00742 int d = (*it)->desktop(); 00743 if (d >= num && !(d == (signed) 0xffffffff || 00744 d == Client::ICONIC_DESKTOP)) { 00745 XEvent ce; 00746 ce.xclient.type = ClientMessage; 00747 ce.xclient.message_type = otk::Property::atoms.net_wm_desktop; 00748 ce.xclient.display = **otk::display; 00749 ce.xclient.window = (*it)->window(); 00750 ce.xclient.format = 32; 00751 ce.xclient.data.l[0] = num - 1; 00752 XSendEvent(**otk::display, _info->rootWindow(), False, 00753 SubstructureNotifyMask | SubstructureRedirectMask, &ce); 00754 } 00755 } 00756 00757 _num_desktops = num; 00758 otk::Property::set(_info->rootWindow(), 00759 otk::Property::atoms.net_number_of_desktops, 00760 otk::Property::atoms.cardinal, _num_desktops); 00761 00762 // set the viewport hint 00763 unsigned long *viewport = new unsigned long[_num_desktops * 2]; 00764 memset(viewport, 0, sizeof(unsigned long) * _num_desktops * 2); 00765 otk::Property::set(_info->rootWindow(), 00766 otk::Property::atoms.net_desktop_viewport, 00767 otk::Property::atoms.cardinal, 00768 viewport, _num_desktops * 2); 00769 delete [] viewport; 00770 00771 // update the work area hint 00772 changeWorkArea(); 00773 00774 // change our desktop if we're on one that no longer exists! 00775 if (_desktop >= num) 00776 changeDesktop(num - 1); 00777 } |
|
Set the client stacking list on the root window. Set the _NET_CLIENT_LIST_STACKING root window property. Definition at line 391 of file screen.cc. References _info, _stacking, otk::Property::atoms, clients, otk::ScreenInfo::rootWindow(), and otk::Property::set(). Referenced by changeClientList(), lowerWindow(), and raiseWindow().
00392 { 00393 Window *windows; 00394 unsigned int size = _stacking.size(); 00395 00396 assert(size == clients.size()); // just making sure.. :) 00397 00398 00399 // create an array of the window ids (from bottom to top, reverse order!) 00400 if (size > 0) { 00401 Window *win_it; 00402 00403 windows = new Window[size]; 00404 win_it = windows; 00405 ClientList::const_reverse_iterator it = _stacking.rbegin(); 00406 const ClientList::const_reverse_iterator end = _stacking.rend(); 00407 for (; it != end; ++it, ++win_it) 00408 *win_it = (*it)->window(); 00409 } else 00410 windows = (Window*) 0; 00411 00412 otk::Property::set(_info->rootWindow(), 00413 otk::Property::atoms.net_client_list_stacking, 00414 otk::Property::atoms.window, windows, size); 00415 00416 if (size) 00417 delete [] windows; 00418 } |
|
Set the list of supported NETWM atoms on the root window.
Definition at line 276 of file screen.cc. References _info, _supportwindow, otk::Property::atoms, otk::ScreenInfo::rootWindow(), and otk::Property::set(). Referenced by Screen().
00277 { 00278 // create the netwm support window 00279 _supportwindow = XCreateSimpleWindow(**otk::display, 00280 _info->rootWindow(), 00281 0, 0, 1, 1, 0, 0, 0); 00282 00283 // set supporting window 00284 otk::Property::set(_info->rootWindow(), 00285 otk::Property::atoms.net_supporting_wm_check, 00286 otk::Property::atoms.window, _supportwindow); 00287 00288 //set properties on the supporting window 00289 otk::Property::set(_supportwindow, otk::Property::atoms.net_wm_name, 00290 otk::Property::utf8, "Openbox"); 00291 otk::Property::set(_supportwindow, 00292 otk::Property::atoms.net_supporting_wm_check, 00293 otk::Property::atoms.window, _supportwindow); 00294 00295 00296 Atom supported[] = { 00297 otk::Property::atoms.net_current_desktop, 00298 otk::Property::atoms.net_number_of_desktops, 00299 otk::Property::atoms.net_desktop_geometry, 00300 otk::Property::atoms.net_desktop_viewport, 00301 otk::Property::atoms.net_active_window, 00302 otk::Property::atoms.net_workarea, 00303 otk::Property::atoms.net_client_list, 00304 otk::Property::atoms.net_client_list_stacking, 00305 otk::Property::atoms.net_desktop_names, 00306 otk::Property::atoms.net_close_window, 00307 otk::Property::atoms.net_wm_name, 00308 otk::Property::atoms.net_wm_visible_name, 00309 otk::Property::atoms.net_wm_icon_name, 00310 otk::Property::atoms.net_wm_visible_icon_name, 00311 /* 00312 otk::Property::atoms.net_wm_desktop, 00313 */ 00314 otk::Property::atoms.net_wm_strut, 00315 otk::Property::atoms.net_wm_window_type, 00316 otk::Property::atoms.net_wm_window_type_desktop, 00317 otk::Property::atoms.net_wm_window_type_dock, 00318 otk::Property::atoms.net_wm_window_type_toolbar, 00319 otk::Property::atoms.net_wm_window_type_menu, 00320 otk::Property::atoms.net_wm_window_type_utility, 00321 otk::Property::atoms.net_wm_window_type_splash, 00322 otk::Property::atoms.net_wm_window_type_dialog, 00323 otk::Property::atoms.net_wm_window_type_normal, 00324 /* 00325 otk::Property::atoms.net_wm_moveresize, 00326 otk::Property::atoms.net_wm_moveresize_size_topleft, 00327 otk::Property::atoms.net_wm_moveresize_size_topright, 00328 otk::Property::atoms.net_wm_moveresize_size_bottomleft, 00329 otk::Property::atoms.net_wm_moveresize_size_bottomright, 00330 otk::Property::atoms.net_wm_moveresize_move, 00331 */ 00332 otk::Property::atoms.net_wm_allowed_actions, 00333 otk::Property::atoms.net_wm_action_move, 00334 otk::Property::atoms.net_wm_action_resize, 00335 otk::Property::atoms.net_wm_action_minimize, 00336 otk::Property::atoms.net_wm_action_shade, 00337 /* otk::Property::atoms.net_wm_action_stick,*/ 00338 otk::Property::atoms.net_wm_action_maximize_horz, 00339 otk::Property::atoms.net_wm_action_maximize_vert, 00340 otk::Property::atoms.net_wm_action_fullscreen, 00341 otk::Property::atoms.net_wm_action_change_desktop, 00342 otk::Property::atoms.net_wm_action_close, 00343 00344 otk::Property::atoms.net_wm_state, 00345 otk::Property::atoms.net_wm_state_modal, 00346 otk::Property::atoms.net_wm_state_maximized_vert, 00347 otk::Property::atoms.net_wm_state_maximized_horz, 00348 otk::Property::atoms.net_wm_state_shaded, 00349 otk::Property::atoms.net_wm_state_skip_taskbar, 00350 otk::Property::atoms.net_wm_state_skip_pager, 00351 otk::Property::atoms.net_wm_state_hidden, 00352 otk::Property::atoms.net_wm_state_fullscreen, 00353 otk::Property::atoms.net_wm_state_above, 00354 otk::Property::atoms.net_wm_state_below, 00355 }; 00356 const int num_supported = sizeof(supported)/sizeof(Atom); 00357 00358 otk::Property::set(_info->rootWindow(), otk::Property::atoms.net_supported, 00359 otk::Property::atoms.atom, supported, num_supported); 00360 } |
|
Set the work area hint on the root window. Set the _NET_WORKAREA root window property. Definition at line 421 of file screen.cc. References _area, _info, _num_desktops, otk::Property::atoms, otk::Rect::height(), otk::ScreenInfo::rootWindow(), otk::Property::set(), otk::Rect::width(), otk::Rect::x(), and otk::Rect::y(). Referenced by calcArea(), and changeNumDesktops().
00421 { 00422 unsigned long *dims = new unsigned long[4 * _num_desktops]; 00423 for (long i = 0; i < _num_desktops; ++i) { 00424 dims[(i * 4) + 0] = _area.x(); 00425 dims[(i * 4) + 1] = _area.y(); 00426 dims[(i * 4) + 2] = _area.width(); 00427 dims[(i * 4) + 3] = _area.height(); 00428 } 00429 otk::Property::set(_info->rootWindow(), otk::Property::atoms.net_workarea, 00430 otk::Property::atoms.cardinal, dims, 4 * _num_desktops); 00431 delete [] dims; 00432 } |
|
Called when a client calls XSendEvent. Some types of client messages are filtered out and sent to more specific event handler functions. Reimplemented from otk::EventHandler. Definition at line 837 of file screen.cc. References otk::Property::atoms, changeDesktop(), changeNumDesktops(), and otk::EventHandler::clientMessageHandler().
00838 { 00839 otk::EventHandler::clientMessageHandler(e); 00840 00841 if (e.format != 32) return; 00842 00843 if (e.message_type == otk::Property::atoms.net_current_desktop) { 00844 changeDesktop(e.data.l[0]); 00845 } else if (e.message_type == otk::Property::atoms.net_number_of_desktops) { 00846 changeNumDesktops(e.data.l[0]); 00847 } 00848 } |
|
Returns the desktop being displayed.
Definition at line 154 of file screen.hh. Referenced by ob::Client::clientMessageHandler(), ob::Client::getDesktop(), ob::Client::mapRequestHandler(), ob::Client::setDesktop(), and ob::Client::setWMState().
00154 { return _desktop; } |
|
An offscreen window which gets focus when nothing else has it.
Definition at line 152 of file screen.hh. Referenced by ob::Openbox::setFocusedClient().
00152 { return _focuswindow; } |
|
Definition at line 807 of file screen.cc. References _info, and otk::ScreenInfo::colormap(). Referenced by ob::Openbox::setFocusedClient().
|
|
Lowers a client window below all others in its stacking layer.
Definition at line 634 of file screen.cc. References _focuswindow, _stacking, changeStackingList(), ob::Client::frame, ob::Client::layer(), ob::Client::modal(), ob::Client::transientFor(), and otk::Widget::window(). Referenced by ob::Client::configureRequestHandler().
00635 { 00636 Window wins[2]; // only ever restack 2 windows. 00637 00638 assert(!_stacking.empty()); // this would be bad 00639 00640 ClientList::iterator it = --_stacking.end(); 00641 const ClientList::iterator end = _stacking.begin(); 00642 00643 if (client->modal() && client->transientFor()) { 00644 // don't let a modal window lower below its transient_for 00645 it = std::find(_stacking.begin(), _stacking.end(), client->transientFor()); 00646 assert(it != _stacking.end()); 00647 00648 wins[0] = (it == _stacking.begin() ? _focuswindow : 00649 ((*(--ClientList::const_iterator(it)))->frame->window())); 00650 wins[1] = client->frame->window(); 00651 if (wins[0] == wins[1]) return; // already right above the window 00652 00653 _stacking.remove(client); 00654 _stacking.insert(it, client); 00655 } else { 00656 for (; it != end && (*it)->layer() < client->layer(); --it); 00657 if (*it == client) return; // already the bottom, return 00658 00659 wins[0] = (*it)->frame->window(); 00660 wins[1] = client->frame->window(); 00661 00662 _stacking.remove(client); 00663 _stacking.insert(++it, client); 00664 } 00665 00666 XRestackWindows(**otk::display, wins, 2); 00667 changeStackingList(); 00668 } |
|
Returns if the screen was successfully managed. If this is false, then the screen should be deleted and should NOT be used. Definition at line 146 of file screen.hh. Referenced by ob::Openbox::Openbox().
00146 { return _managed; } |
|
Manage any pre-existing windows on the screen.
Definition at line 162 of file screen.cc. References _info, manageWindow(), and otk::ScreenInfo::rootWindow().
00163 { 00164 unsigned int i, j, nchild; 00165 Window r, p, *children; 00166 XQueryTree(**otk::display, _info->rootWindow(), &r, &p, 00167 &children, &nchild); 00168 00169 // preen the window list of all icon windows... for better dockapp support 00170 for (i = 0; i < nchild; i++) { 00171 if (children[i] == None) continue; 00172 00173 XWMHints *wmhints = XGetWMHints(**otk::display, 00174 children[i]); 00175 00176 if (wmhints) { 00177 if ((wmhints->flags & IconWindowHint) && 00178 (wmhints->icon_window != children[i])) { 00179 for (j = 0; j < nchild; j++) { 00180 if (children[j] == wmhints->icon_window) { 00181 children[j] = None; 00182 break; 00183 } 00184 } 00185 } 00186 00187 XFree(wmhints); 00188 } 00189 } 00190 00191 // manage shown windows 00192 for (i = 0; i < nchild; ++i) { 00193 if (children[i] == None) 00194 continue; 00195 00196 XWindowAttributes attrib; 00197 if (XGetWindowAttributes(**otk::display, children[i], &attrib)) { 00198 if (attrib.override_redirect) continue; 00199 00200 if (attrib.map_state != IsUnmapped) { 00201 manageWindow(children[i]); 00202 } 00203 } 00204 } 00205 00206 XFree(children); 00207 } |
|
Manage a client window. This gives the window a frame, reparents it, selects events on it, etc. Definition at line 435 of file screen.cc. References _desktop, _stacking, ob::Openbox::addClient(), ob::Client::applyStartupState(), ob::Openbox::bindings(), ob::Frame::button_alldesk(), ob::Frame::button_close(), ob::Frame::button_iconify(), ob::Frame::button_max(), changeClientList(), otk::EventDispatcher::clearHandler(), clients, ob::Client::desktop(), ob::Bindings::fireEvent(), ob::Client::frame, ob::Bindings::grabButtons(), ob::Frame::grabClient(), ob::Frame::grip_left(), ob::Frame::grip_right(), ob::Frame::handle(), ob::Frame::label(), ob::openbox, ob::Frame::plate(), raiseWindow(), otk::EventDispatcher::registerHandler(), otk::Widget::show(), ob::Openbox::state(), ob::Frame::titlebar(), ob::Client::toggleClientBorder(), updateStrut(), and otk::Widget::window(). Referenced by manageExisting(), and mapRequestHandler().
00436 { 00437 Client *client = 0; 00438 XWMHints *wmhint; 00439 XSetWindowAttributes attrib_set; 00440 XEvent e; 00441 XWindowAttributes attrib; 00442 00443 otk::display->grab(); 00444 00445 // check if it has already been unmapped by the time we started mapping 00446 // the grab does a sync so we don't have to here 00447 if (XCheckTypedWindowEvent(**otk::display, window, DestroyNotify, &e) || 00448 XCheckTypedWindowEvent(**otk::display, window, UnmapNotify, &e)) { 00449 XPutBackEvent(**otk::display, &e); 00450 00451 otk::display->ungrab(); 00452 return; // don't manage it 00453 } 00454 00455 if (!XGetWindowAttributes(**otk::display, window, &attrib) || 00456 attrib.override_redirect) { 00457 otk::display->ungrab(); 00458 return; // don't manage it 00459 } 00460 00461 // is the window a docking app 00462 if ((wmhint = XGetWMHints(**otk::display, window))) { 00463 if ((wmhint->flags & StateHint) && 00464 wmhint->initial_state == WithdrawnState) { 00465 //slit->addClient(w); // XXX: make dock apps work! 00466 00467 otk::display->ungrab(); 00468 XFree(wmhint); 00469 return; 00470 } 00471 XFree(wmhint); 00472 } 00473 00474 // choose the events we want to receive on the CLIENT window 00475 attrib_set.event_mask = Client::event_mask; 00476 attrib_set.do_not_propagate_mask = Client::no_propagate_mask; 00477 XChangeWindowAttributes(**otk::display, window, 00478 CWEventMask|CWDontPropagate, &attrib_set); 00479 00480 // create the Client class, which gets all of the hints on the window 00481 client = new Client(_number, window); 00482 // register for events 00483 openbox->registerHandler(window, client); 00484 // add to the wm's map 00485 openbox->addClient(window, client); 00486 00487 // we dont want a border on the client 00488 client->toggleClientBorder(false); 00489 00490 // specify that if we exit, the window should not be destroyed and should be 00491 // reparented back to root automatically 00492 XChangeSaveSet(**otk::display, window, SetModeInsert); 00493 00494 // create the decoration frame for the client window 00495 client->frame = new Frame(client, &_style); 00496 // register the plate for events (map req's) 00497 // this involves removing itself from the handler list first, since it is 00498 // auto added to the list, being a widget. we won't get any events on the 00499 // plate except for events for the client (SubstructureRedirectMask) 00500 openbox->clearHandler(client->frame->plate()); 00501 openbox->registerHandler(client->frame->plate(), client); 00502 00503 // add to the wm's map 00504 openbox->addClient(client->frame->window(), client); 00505 openbox->addClient(client->frame->plate(), client); 00506 openbox->addClient(client->frame->titlebar(), client); 00507 openbox->addClient(client->frame->label(), client); 00508 openbox->addClient(client->frame->button_max(), client); 00509 openbox->addClient(client->frame->button_iconify(), client); 00510 openbox->addClient(client->frame->button_alldesk(), client); 00511 openbox->addClient(client->frame->button_close(), client); 00512 openbox->addClient(client->frame->handle(), client); 00513 openbox->addClient(client->frame->grip_left(), client); 00514 openbox->addClient(client->frame->grip_right(), client); 00515 00516 // reparent the client to the frame 00517 client->frame->grabClient(); 00518 00519 if (openbox->state() != Openbox::State_Starting) { 00520 // position the window intelligenty .. hopefully :) 00521 // call the python PLACEWINDOW binding 00522 EventData data(_number, client, EventAction::PlaceWindow, 0); 00523 openbox->bindings()->fireEvent(&data); 00524 } 00525 00526 EventData ddata(_number, client, EventAction::DisplayingWindow, 0); 00527 openbox->bindings()->fireEvent(&ddata); 00528 00529 // if on the current desktop.. (or all desktops) 00530 if (client->desktop() == _desktop || 00531 client->desktop() == (signed)0xffffffff) { 00532 client->frame->show(); 00533 } 00534 00535 client->applyStartupState(); 00536 00537 otk::display->ungrab(); 00538 00539 // add to the screen's list 00540 clients.push_back(client); 00541 // once the client is in the list, update our strut to include the new 00542 // client's (it is good that this happens after window placement!) 00543 updateStrut(); 00544 // this puts into the stacking order, then raises it 00545 _stacking.push_back(client); 00546 raiseWindow(client); 00547 // update the root properties 00548 changeClientList(); 00549 00550 openbox->bindings()->grabButtons(true, client); 00551 00552 EventData ndata(_number, client, EventAction::NewWindow, 0); 00553 openbox->bindings()->fireEvent(&ndata); 00554 00555 #ifdef DEBUG 00556 printf("Managed window 0x%lx frame 0x%lx\n", 00557 window, client->frame->window()); 00558 #endif 00559 } |
|
Called when a different client tries to map a window.
Reimplemented from otk::EventHandler. Definition at line 851 of file screen.cc. References ob::Openbox::findClient(), manageWindow(), otk::EventHandler::mapRequestHandler(), and ob::openbox.
00852 { 00853 otk::EventHandler::mapRequestHandler(e); 00854 00855 #ifdef DEBUG 00856 printf("MapRequest for 0x%lx\n", e.window); 00857 #endif // DEBUG 00858 00859 Client *c = openbox->findClient(e.window); 00860 if (c) { 00861 #ifdef DEBUG 00862 printf("DEBUG: MAP REQUEST CAUGHT IN SCREEN. IGNORED.\n"); 00863 #endif 00864 } else 00865 manageWindow(e.window); 00866 } |
|
Definition at line 139 of file screen.hh. Referenced by ob::Openbox::setFocusedClient().
00139 { return _number; } |
|
Returns the number of desktops.
Definition at line 156 of file screen.hh.
00156 { return _num_desktops; } |
|
Called when a property of a window changes.
Reimplemented from otk::EventHandler. Definition at line 816 of file screen.cc. References _info, otk::Property::atoms, otk::EventHandler::propertyHandler(), otk::ScreenInfo::rootWindow(), and updateDesktopNames().
00817 { 00818 otk::EventHandler::propertyHandler(e); 00819 00820 // compress changes to a single property into a single change 00821 XEvent ce; 00822 while (XCheckTypedWindowEvent(**otk::display, _info->rootWindow(), 00823 e.type, &ce)) { 00824 // XXX: it would be nice to compress ALL changes to a property, not just 00825 // changes in a row without other props between. 00826 if (ce.xproperty.atom != e.atom) { 00827 XPutBackEvent(**otk::display, &ce); 00828 break; 00829 } 00830 } 00831 00832 if (e.atom == otk::Property::atoms.net_desktop_names) 00833 updateDesktopNames(); 00834 } |
|
Raises a client window above all others in its stacking layer.
raiseWindow has a couple of constraints that lowerWindow does not. Definition at line 670 of file screen.cc. References _focuswindow, _stacking, changeStackingList(), ob::Client::frame, ob::Client::layer(), ob::Client::modalChild(), and otk::Widget::window(). Referenced by ob::Client::calcLayer(), ob::Client::clientMessageHandler(), ob::Client::configureRequestHandler(), ob::Client::fullscreen(), and manageWindow().
00671 { 00672 Window wins[2]; // only ever restack 2 windows. 00673 00674 assert(!_stacking.empty()); // this would be bad 00675 00676 // remove the client before looking so we can't run into ourselves 00677 _stacking.remove(client); 00678 00679 ClientList::iterator it = _stacking.begin(); 00680 const ClientList::iterator end = _stacking.end(); 00681 00682 // the stacking list is from highest to lowest 00683 for (; it != end && (*it)->layer() > client->layer(); ++it); 00684 00685 /* 00686 if our new position is the top, we want to stack under the _focuswindow 00687 otherwise, we want to stack under the previous window in the stack. 00688 */ 00689 wins[0] = (it == _stacking.begin() ? _focuswindow : 00690 ((*(--ClientList::const_iterator(it)))->frame->window())); 00691 wins[1] = client->frame->window(); 00692 00693 _stacking.insert(it, client); 00694 00695 XRestackWindows(**otk::display, wins, 2); 00696 00697 // if the window has a modal child, then raise it after us to put it on top 00698 if (client->modalChild()) 00699 raiseWindow(client->modalChild()); 00700 else 00701 changeStackingList(); // no need to do this twice! 00702 } |
|
Sets the name of a desktop by changing the root window property.
Definition at line 793 of file screen.cc. References _desktop_names, _info, _num_desktops, otk::Property::atoms, otk::ScreenInfo::rootWindow(), otk::Property::set(), otk::Property::StringVect, and otk::Property::utf8.
00794 { 00795 assert(i >= 0); 00796 00797 if (i >= _num_desktops) return; 00798 00799 otk::Property::StringVect newnames = _desktop_names; 00800 newnames[i] = name; 00801 otk::Property::set(_info->rootWindow(), 00802 otk::Property::atoms.net_desktop_names, 00803 otk::Property::utf8, newnames); 00804 } |
|
Returns the style in use on the screen.
Definition at line 150 of file screen.hh.
00150 { return &_style; } |
|
Unmanage a client. This removes the window's frame, reparents it to root, unselects events on it, etc.
Definition at line 562 of file screen.cc. References _stacking, ob::Openbox::bindings(), ob::Frame::button_alldesk(), ob::Frame::button_close(), ob::Frame::button_iconify(), ob::Frame::button_max(), changeClientList(), otk::EventDispatcher::clearHandler(), clients, ob::Bindings::fireEvent(), ob::Client::frame, ob::Bindings::grabButtons(), ob::Frame::grip_left(), ob::Frame::grip_right(), ob::Frame::handle(), otk::Widget::hide(), ob::Frame::label(), ob::openbox, ob::Frame::plate(), ob::Frame::releaseClient(), ob::Openbox::removeClient(), ob::Client::setModal(), ob::Frame::titlebar(), ob::Client::toggleClientBorder(), ob::Client::unfocus(), updateStrut(), otk::Widget::window(), and ob::Client::window(). Referenced by ob::Client::destroyHandler(), ob::Client::reparentHandler(), ob::Client::unmapHandler(), and ~Screen().
00563 { 00564 Frame *frame = client->frame; 00565 00566 // call the python CLOSEWINDOW binding 00567 EventData data(_number, client, EventAction::CloseWindow, 0); 00568 openbox->bindings()->fireEvent(&data); 00569 00570 openbox->bindings()->grabButtons(false, client); 00571 00572 // remove from the wm's map 00573 openbox->removeClient(client->window()); 00574 openbox->removeClient(frame->window()); 00575 openbox->removeClient(frame->plate()); 00576 openbox->removeClient(frame->titlebar()); 00577 openbox->removeClient(frame->label()); 00578 openbox->removeClient(frame->button_max()); 00579 openbox->removeClient(frame->button_iconify()); 00580 openbox->removeClient(frame->button_alldesk()); 00581 openbox->removeClient(frame->button_close()); 00582 openbox->removeClient(frame->handle()); 00583 openbox->removeClient(frame->grip_left()); 00584 openbox->removeClient(frame->grip_right()); 00585 // unregister for handling events 00586 openbox->clearHandler(client->window()); 00587 00588 // remove the window from our save set 00589 XChangeSaveSet(**otk::display, client->window(), SetModeDelete); 00590 00591 // we dont want events no more 00592 XSelectInput(**otk::display, client->window(), NoEventMask); 00593 00594 frame->hide(); 00595 00596 // give the client its border back 00597 client->toggleClientBorder(true); 00598 00599 // reparent the window out of the frame 00600 frame->releaseClient(); 00601 00602 #ifdef DEBUG 00603 Window framewin = client->frame->window(); 00604 #endif 00605 delete client->frame; 00606 client->frame = 0; 00607 00608 // remove from the stacking order 00609 _stacking.remove(client); 00610 00611 // remove from the screen's list 00612 clients.remove(client); 00613 00614 // once the client is out of the list, update our strut to remove it's 00615 // influence 00616 updateStrut(); 00617 00618 // unset modal before dropping our focus 00619 client->setModal(false); 00620 00621 // unfocus the client (calls the focus callbacks) 00622 client->unfocus(); 00623 00624 #ifdef DEBUG 00625 printf("Unmanaged window 0x%lx frame 0x%lx\n", client->window(), framewin); 00626 #endif 00627 00628 delete client; 00629 00630 // update the root properties 00631 changeClientList(); 00632 } |
|
Get desktop names from the root window property.
Definition at line 780 of file screen.cc. References _desktop_names, _info, _num_desktops, otk::Property::atoms, otk::Property::get(), otk::ScreenInfo::rootWindow(), and otk::Property::utf8. Referenced by propertyHandler().
00781 { 00782 unsigned long num = (unsigned) -1; 00783 00784 if (!otk::Property::get(_info->rootWindow(), 00785 otk::Property::atoms.net_desktop_names, 00786 otk::Property::utf8, &num, &_desktop_names)) 00787 _desktop_names.clear(); 00788 while ((long)_desktop_names.size() < _num_desktops) 00789 _desktop_names.push_back("Unnamed"); 00790 } |
|
Update's the screen's combined strut of all the clients. Clients should call this whenever they change their strut. Definition at line 210 of file screen.cc. References _strut, otk::Strut::bottom, calcArea(), clients, otk::Strut::left, otk::Strut::right, and otk::Strut::top. Referenced by manageWindow(), unmanageWindow(), and ob::Client::updateStrut().
00211 { 00212 _strut.left = _strut.right = _strut.top = _strut.bottom = 0; 00213 00214 ClientList::iterator it, end = clients.end(); 00215 for (it = clients.begin(); it != end; ++it) { 00216 const otk::Strut &s = (*it)->strut(); 00217 _strut.left = std::max(_strut.left, s.left); 00218 _strut.right = std::max(_strut.right, s.right); 00219 _strut.top = std::max(_strut.top, s.top); 00220 _strut.bottom = std::max(_strut.bottom, s.bottom); 00221 } 00222 calcArea(); 00223 } |
|
Area usable for placement etc (total - struts).
Definition at line 68 of file screen.hh. Referenced by calcArea(), and changeWorkArea(). |
|
The desktop currently being displayed.
Definition at line 84 of file screen.hh. Referenced by changeDesktop(), changeNumDesktops(), manageWindow(), and Screen(). |
|
The names of all desktops.
Definition at line 90 of file screen.hh. Referenced by setDesktopName(), and updateDesktopNames(). |
|
An offscreen window which gets focus when nothing else has it.
Definition at line 74 of file screen.hh. Referenced by lowerWindow(), raiseWindow(), and Screen(). |
|
Information about this screen.
Definition at line 59 of file screen.hh. Referenced by calcArea(), changeClientList(), changeDesktop(), changeNumDesktops(), changeStackingList(), changeSupportedAtoms(), changeWorkArea(), installColormap(), manageExisting(), propertyHandler(), Screen(), setDesktopName(), updateDesktopNames(), and ~Screen(). |
|
Was Openbox able to manage the screen?
|
|
The number of desktops.
Definition at line 87 of file screen.hh. Referenced by changeDesktop(), changeNumDesktops(), changeWorkArea(), Screen(), setDesktopName(), and updateDesktopNames(). |
|
The number of the screen on the X server.
|
|
Is the root colormap currently installed?
|
|
A list of all managed clients on the screen, in their stacking order.
Definition at line 81 of file screen.hh. Referenced by changeStackingList(), lowerWindow(), manageWindow(), raiseWindow(), and unmanageWindow(). |
|
Combined strut from all of the clients' struts.
Definition at line 71 of file screen.hh. Referenced by calcArea(), and updateStrut(). |
|
The style with which to render on the screen.
Definition at line 62 of file screen.hh. Referenced by Screen(). |
|
An offscreen window which shows that a NETWM compliant window manager is running.
Definition at line 78 of file screen.hh. Referenced by changeSupportedAtoms(). |
|
All managed clients on the screen (in order of being mapped).
Definition at line 49 of file screen.hh. Referenced by ob::Bindings::addButton(), calcArea(), changeClientList(), changeDesktop(), changeNumDesktops(), changeStackingList(), manageWindow(), ob::Bindings::removeAllButtons(), unmanageWindow(), updateStrut(), and ~Screen(). |
|
Initial value: ColormapChangeMask | EnterWindowMask | LeaveWindowMask | PropertyChangeMask | SubstructureNotifyMask | SubstructureRedirectMask | ButtonPressMask | ButtonReleaseMask |