X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2Fscreen.cc;h=72a33b41fd4f8a571647794115145bdd28172937;hb=3cca07840b571a18e599d66b4108626cbd48788d;hp=1033f8d8ac822bba34472406d71beb0ee90fded2;hpb=48741b97c229dc6515fcf8e06bc4da47f9abab72;p=chaz%2Fopenbox diff --git a/src/screen.cc b/src/screen.cc index 1033f8d8..72a33b41 100644 --- a/src/screen.cc +++ b/src/screen.cc @@ -48,7 +48,8 @@ namespace ob { Screen::Screen(int screen) : WidgetBase(WidgetBase::Type_Root), - _number(screen) + _number(screen), + _style(screen, "") { assert(screen >= 0); assert(screen < ScreenCount(**otk::display)); _info = otk::display->screenInfo(screen); @@ -73,13 +74,8 @@ Screen::Screen(int screen) XDefineCursor(**otk::display, _info->rootWindow(), openbox->cursors().session); - // initialize the shit that is used for all drawing on the screen - _image_control = new otk::ImageControl(_info, true); - _image_control->installRootColormap(); - _root_cmap_installed = True; - - // initialize the screen's style - _style.setImageControl(_image_control); + // XXX: initialize the screen's style + /* otk::ustring stylepath; python_get_string("theme", &stylepath); otk::Configuration sconfig(false); @@ -92,6 +88,8 @@ Screen::Screen(int screen) } } _style.load(sconfig); + */ + otk::display->renderControl(_number)->drawRoot(*_style.rootColor()); // set up notification of netwm support changeSupportedAtoms(); @@ -136,7 +134,7 @@ Screen::Screen(int screen) openbox->registerHandler(_info->rootWindow(), this); // call the python Startup callbacks - EventData data(_number, 0, EventShutdown, 0); + EventData data(_number, 0, EventAction::Shutdown, 0); openbox->bindings()->fireEvent(&data); } @@ -152,13 +150,11 @@ Screen::~Screen() unmanageWindow(clients.front()); // call the python Shutdown callbacks - EventData data(_number, 0, EventShutdown, 0); + EventData data(_number, 0, EventAction::Shutdown, 0); openbox->bindings()->fireEvent(&data); XDestroyWindow(**otk::display, _focuswindow); XDestroyWindow(**otk::display, _supportwindow); - - delete _image_control; } @@ -228,7 +224,7 @@ void Screen::updateStrut() void Screen::calcArea() { - otk::Rect old_area = _area; +// otk::Rect old_area = _area; /* #ifdef XINERAMA @@ -265,7 +261,7 @@ void Screen::calcArea() #endif // XINERAMA */ - if (old_area != _area) + //if (old_area != _area) // XXX: re-maximize windows changeWorkArea(); @@ -328,16 +324,18 @@ void Screen::changeSupportedAtoms() otk::Property::atoms.net_wm_moveresize_size_bottomright, otk::Property::atoms.net_wm_moveresize_move, */ -/* otk::Property::atoms.net_wm_allowed_actions, otk::Property::atoms.net_wm_action_move, otk::Property::atoms.net_wm_action_resize, + otk::Property::atoms.net_wm_action_minimize, otk::Property::atoms.net_wm_action_shade, +/* otk::Property::atoms.net_wm_action_stick,*/ otk::Property::atoms.net_wm_action_maximize_horz, otk::Property::atoms.net_wm_action_maximize_vert, + otk::Property::atoms.net_wm_action_fullscreen, otk::Property::atoms.net_wm_action_change_desktop, otk::Property::atoms.net_wm_action_close, -*/ + otk::Property::atoms.net_wm_state, otk::Property::atoms.net_wm_state_modal, otk::Property::atoms.net_wm_state_maximized_vert, @@ -435,16 +433,34 @@ void Screen::manageWindow(Window window) Client *client = 0; XWMHints *wmhint; XSetWindowAttributes attrib_set; + XEvent e; + XWindowAttributes attrib; otk::display->grab(); + // check if it has already been unmapped by the time we started mapping + // the grab does a sync so we don't have to here + if (XCheckTypedWindowEvent(**otk::display, window, DestroyNotify, &e) || + XCheckTypedWindowEvent(**otk::display, window, UnmapNotify, &e)) { + XPutBackEvent(**otk::display, &e); + + otk::display->ungrab(); + return; // don't manage it + } + + if (!XGetWindowAttributes(**otk::display, window, &attrib) || + attrib.override_redirect) { + otk::display->ungrab(); + return; // don't manage it + } + // is the window a docking app if ((wmhint = XGetWMHints(**otk::display, window))) { if ((wmhint->flags & StateHint) && wmhint->initial_state == WithdrawnState) { //slit->addClient(w); // XXX: make dock apps work! - otk::display->ungrab(); + otk::display->ungrab(); XFree(wmhint); return; } @@ -473,14 +489,12 @@ void Screen::manageWindow(Window window) // create the decoration frame for the client window client->frame = new Frame(client, &_style); - - if (!(openbox->state() == Openbox::State_Starting || - client->positionRequested())) { - // position the window intelligenty .. hopefully :) - // call the python PLACEWINDOW binding - EventData data(_number, client, EventPlaceWindow, 0); - openbox->bindings()->fireEvent(&data); - } + // register the plate for events (map req's) + // this involves removing itself from the handler list first, since it is + // auto added to the list, being a widget. we won't get any events on the + // plate except for events for the client (SubstructureRedirectMask) + openbox->clearHandler(client->frame->plate()); + openbox->registerHandler(client->frame->plate(), client); // add to the wm's map openbox->addClient(client->frame->window(), client); @@ -489,7 +503,7 @@ void Screen::manageWindow(Window window) openbox->addClient(client->frame->label(), client); openbox->addClient(client->frame->button_max(), client); openbox->addClient(client->frame->button_iconify(), client); - openbox->addClient(client->frame->button_stick(), client); + openbox->addClient(client->frame->button_alldesk(), client); openbox->addClient(client->frame->button_close(), client); openbox->addClient(client->frame->handle(), client); openbox->addClient(client->frame->grip_left(), client); @@ -498,18 +512,32 @@ void Screen::manageWindow(Window window) // reparent the client to the frame client->frame->grabClient(); + if (!(openbox->state() == Openbox::State_Starting || + client->positionRequested())) { + // position the window intelligenty .. hopefully :) + // call the python PLACEWINDOW binding + EventData data(_number, client, EventAction::PlaceWindow, 0); + openbox->bindings()->fireEvent(&data); + } + + EventData ddata(_number, client, EventAction::DisplayingWindow, 0); + openbox->bindings()->fireEvent(&ddata); + // if on the current desktop.. (or all desktops) if (client->desktop() == _desktop || client->desktop() == (signed)0xffffffff) { client->frame->show(); } - - // XXX: handle any requested states such as maximized + + client->applyStartupState(); otk::display->ungrab(); // add to the screen's list clients.push_back(client); + // once the client is in the list, update our strut to include the new + // client's (it is good that this happens after window placement!) + updateStrut(); // this puts into the stacking order, then raises it _stacking.push_back(client); raiseWindow(client); @@ -518,12 +546,12 @@ void Screen::manageWindow(Window window) openbox->bindings()->grabButtons(true, client); - // call the python NEWWINDOW binding - EventData data(_number, client, EventNewWindow, 0); - openbox->bindings()->fireEvent(&data); + EventData ndata(_number, client, EventAction::NewWindow, 0); + openbox->bindings()->fireEvent(&ndata); #ifdef DEBUG - printf("Managed window 0x%lx\n", window); + printf("Managed window 0x%lx frame 0x%lx\n", + window, client->frame->window()); #endif } @@ -533,7 +561,7 @@ void Screen::unmanageWindow(Client *client) Frame *frame = client->frame; // call the python CLOSEWINDOW binding - EventData data(_number, client, EventCloseWindow, 0); + EventData data(_number, client, EventAction::CloseWindow, 0); openbox->bindings()->fireEvent(&data); openbox->bindings()->grabButtons(false, client); @@ -546,7 +574,7 @@ void Screen::unmanageWindow(Client *client) openbox->removeClient(frame->label()); openbox->removeClient(frame->button_max()); openbox->removeClient(frame->button_iconify()); - openbox->removeClient(frame->button_stick()); + openbox->removeClient(frame->button_alldesk()); openbox->removeClient(frame->button_close()); openbox->removeClient(frame->handle()); openbox->removeClient(frame->grip_left()); @@ -568,6 +596,9 @@ void Screen::unmanageWindow(Client *client) // reparent the window out of the frame frame->releaseClient(); +#ifdef DEBUG + Window framewin = client->frame->window(); +#endif delete client->frame; client->frame = 0; @@ -577,11 +608,15 @@ void Screen::unmanageWindow(Client *client) // remove from the screen's list clients.remove(client); + // once the client is out of the list, update our strut to remove it's + // influence + updateStrut(); + // unfocus the client (calls the focus callbacks) client->unfocus(); #ifdef DEBUG - printf("Unmanaged window 0x%lx\n", client->window()); + printf("Unmanaged window 0x%lx frame 0x%lx\n", client->window(), framewin); #endif delete client; @@ -597,7 +632,7 @@ void Screen::lowerWindow(Client *client) assert(!_stacking.empty()); // this would be bad Client::List::iterator it = --_stacking.end(); - Client::List::const_iterator end = _stacking.begin(); + const Client::List::iterator end = _stacking.begin(); for (; it != end && (*it)->layer() < client->layer(); --it); if (*it == client) return; // already the bottom, return @@ -622,7 +657,7 @@ void Screen::raiseWindow(Client *client) _stacking.remove(client); Client::List::iterator it = _stacking.begin(); - Client::List::const_iterator end = _stacking.end(); + const Client::List::iterator end = _stacking.end(); // the stacking list is from highest to lowest for (; it != end && (*it)->layer() > client->layer(); ++it); @@ -767,30 +802,13 @@ void Screen::mapRequestHandler(const XMapRequestEvent &e) printf("MapRequest for 0x%lx\n", e.window); #endif // DEBUG - /* - MapRequest events come here even after the window exists instead of going - right to the client window, because of how they are sent and their struct - layout. - */ Client *c = openbox->findClient(e.window); - if (c) { - // send a net_active_window message - XEvent ce; - ce.xclient.type = ClientMessage; - ce.xclient.message_type = otk::Property::atoms.net_active_window; - ce.xclient.display = **otk::display; - ce.xclient.window = c->window(); - ce.xclient.format = 32; - ce.xclient.data.l[0] = 0l; - ce.xclient.data.l[1] = 0l; - ce.xclient.data.l[2] = 0l; - ce.xclient.data.l[3] = 0l; - ce.xclient.data.l[4] = 0l; - XSendEvent(**otk::display, _info->rootWindow(), false, - SubstructureRedirectMask | SubstructureNotifyMask, - &ce); +#ifdef DEBUG + printf("DEBUG: MAP REQUEST CAUGHT IN SCREEN. IGNORED.\n"); +#endif } else manageWindow(e.window); } + }