X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fclient.cc;h=b5bec898b77cfe4d8578a5d9f6a3690c179ec4b3;hb=a0350e27b311db5cab49035752d3852ee68bf8a2;hp=a22a18a6481afd40d9a4b650805fe04dcfcf976b;hpb=0816364a039fb0a0b2f989394ffb6af0b5221b3f;p=chaz%2Fopenbox diff --git a/src/client.cc b/src/client.cc index a22a18a6..b5bec898 100644 --- a/src/client.cc +++ b/src/client.cc @@ -7,7 +7,6 @@ #include "client.hh" #include "frame.hh" #include "screen.hh" -#include "bbscreen.hh" #include "openbox.hh" #include "otk/display.hh" #include "otk/property.hh" @@ -37,9 +36,11 @@ OBClient::OBClient(int screen, Window window) // update EVERYTHING the first time!! // the state is kinda assumed to be normal. is this right? XXX - _wmstate = NormalState; + _wmstate = NormalState; _iconic = false; // no default decors or functions, each has to be enabled _decorations = _functions = 0; + // start unfocused + _focused = false; getArea(); getDesktop(); @@ -89,53 +90,7 @@ OBClient::OBClient(int screen, Window window) updateIconTitle(); updateClass(); -/* -#ifdef DEBUG - printf("Mapped window: 0x%lx\n" - " title: \t%s\t icon title: \t%s\n" - " app name: \t%s\t\t class: \t%s\n" - " position: \t%d, %d\t\t size: \t%d, %d\n" - " desktop: \t%lu\t\t group: \t0x%lx\n" - " type: \t%d\t\t min size \t%d, %d\n" - " base size \t%d, %d\t\t max size \t%d, %d\n" - " size incr \t%d, %d\t\t gravity \t%d\n" - " wm state \t%ld\t\t can be focused:\t%s\n" - " notify focus: \t%s\t\t urgent: \t%s\n" - " shaped: \t%s\t\t modal: \t%s\n" - " shaded: \t%s\t\t iconic: \t%s\n" - " vert maximized:\t%s\t\t horz maximized:\t%s\n" - " fullscreen: \t%s\t\t floating: \t%s\n" - " requested pos: \t%s\n", - _window, - _title.c_str(), - _icon_title.c_str(), - _app_name.c_str(), - _app_class.c_str(), - _area.x(), _area.y(), - _area.width(), _area.height(), - _desktop, - _group, - _type, - _min_x, _min_y, - _base_x, _base_y, - _max_x, _max_y, - _inc_x, _inc_y, - _gravity, - _wmstate, - _can_focus ? "yes" : "no", - _focus_notify ? "yes" : "no", - _urgent ? "yes" : "no", - _shaped ? "yes" : "no", - _modal ? "yes" : "no", - _shaded ? "yes" : "no", - _iconic ? "yes" : "no", - _max_vert ? "yes" : "no", - _max_horz ? "yes" : "no", - _fullscreen ? "yes" : "no", - _floating ? "yes" : "no", - _positioned ? "yes" : "no"); -#endif -*/ + calcLayer(); } @@ -293,7 +248,8 @@ void OBClient::getState() { const otk::OBProperty *property = Openbox::instance->property(); - _modal = _shaded = _max_horz = _max_vert = _fullscreen = _floating = false; + _modal = _shaded = _max_horz = _max_vert = _fullscreen = _above = _below = + false; unsigned long *state; unsigned long num = (unsigned) -1; @@ -315,6 +271,12 @@ void OBClient::getState() else if (state[i] == property->atom(otk::OBProperty::net_wm_state_maximized_horz)) _max_horz = true; + else if (state[i] == + property->atom(otk::OBProperty::net_wm_state_above)) + _above = true; + else if (state[i] == + property->atom(otk::OBProperty::net_wm_state_below)) + _below = true; } delete [] state; @@ -341,6 +303,17 @@ void OBClient::getShaped() } +void OBClient::calcLayer() { + if (_iconic) _layer = OBScreen::Layer_Icon; + else if (_type == Type_Desktop) _layer = OBScreen::Layer_Desktop; + else if (_type == Type_Dock) _layer = OBScreen::Layer_Top; + else if (_fullscreen) _layer = OBScreen::Layer_Fullscreen; + else if (_above) _layer = OBScreen::Layer_Above; + else if (_below) _layer = OBScreen::Layer_Below; + else _layer = OBScreen::Layer_Normal; +} + + void OBClient::updateProtocols() { const otk::OBProperty *property = Openbox::instance->property(); @@ -460,6 +433,9 @@ void OBClient::updateTitle() if (_title.empty()) _title = _("Unnamed Window"); + + if (frame) + frame->setTitle(_title); } @@ -591,8 +567,10 @@ void OBClient::setState(StateAction action, long data1, long data2) else if (state == property->atom(otk::OBProperty::net_wm_state_fullscreen)) action = _fullscreen ? State_Remove : State_Add; - else if (state == property->atom(otk::OBProperty::net_wm_state_floating)) - action = _floating ? State_Remove : State_Add; + else if (state == property->atom(otk::OBProperty::net_wm_state_above)) + action = _above ? State_Remove : State_Add; + else if (state == property->atom(otk::OBProperty::net_wm_state_below)) + action = _below ? State_Remove : State_Add; } if (action == State_Add) { @@ -621,10 +599,15 @@ void OBClient::setState(StateAction action, long data1, long data2) _fullscreen = true; // XXX: raise the window n shit } else if (state == - property->atom(otk::OBProperty::net_wm_state_floating)) { - if (_floating) continue; - _floating = true; + property->atom(otk::OBProperty::net_wm_state_above)) { + if (_above) continue; + _above = true; // XXX: raise the window n shit + } else if (state == + property->atom(otk::OBProperty::net_wm_state_below)) { + if (_below) continue; + _below = true; + // XXX: lower the window n shit } } else { // action == State_Remove @@ -652,13 +635,20 @@ void OBClient::setState(StateAction action, long data1, long data2) _fullscreen = false; // XXX: lower the window to its proper layer } else if (state == - property->atom(otk::OBProperty::net_wm_state_floating)) { - if (!_floating) continue; - _floating = false; + property->atom(otk::OBProperty::net_wm_state_above)) { + if (!_above) continue; + _above = false; // XXX: lower the window to its proper layer + } else if (state == + property->atom(otk::OBProperty::net_wm_state_below)) { + if (!_below) continue; + _below = false; + // XXX: raise the window to its proper layer } } } + calcLayer(); + Openbox::instance->screen(_screen)->restack(true, this); // raise } @@ -859,8 +849,63 @@ void OBClient::close() } +bool OBClient::focus() +{ + if (!_can_focus || _focused) return false; + + XSetInputFocus(otk::OBDisplay::display, _window, RevertToNone, CurrentTime); + return true; +} + + +void OBClient::unfocus() +{ + if (!_focused) return; + + assert(Openbox::instance->focusedClient() == this); + Openbox::instance->setFocusedClient(0); +} + + +void OBClient::focusHandler(const XFocusChangeEvent &e) +{ +#ifdef DEBUG + printf("FocusIn for 0x%lx\n", e.window); +#endif // DEBUG + + OtkEventHandler::focusHandler(e); + + frame->focus(); + _focused = true; + + Openbox::instance->setFocusedClient(this); +} + + +void OBClient::unfocusHandler(const XFocusChangeEvent &e) +{ +#ifdef DEBUG + printf("FocusOut for 0x%lx\n", e.window); +#endif // DEBUG + + OtkEventHandler::unfocusHandler(e); + + frame->unfocus(); + _focused = false; + + if (Openbox::instance->focusedClient() == this) { + printf("UNFOCUSED!\n"); + Openbox::instance->setFocusedClient(this); + } +} + + void OBClient::configureRequestHandler(const XConfigureRequestEvent &e) { +#ifdef DEBUG + printf("ConfigureRequest for 0x%lx\n", e.window); +#endif // DEBUG + OtkEventHandler::configureRequestHandler(e); // XXX: if we are iconic (or shaded? (fvwm does that)) ignore the event @@ -868,7 +913,7 @@ void OBClient::configureRequestHandler(const XConfigureRequestEvent &e) if (e.value_mask & CWBorderWidth) _border_width = e.border_width; - // resize, then move, as specified in the EWMH section 7.7 + // resize, then move, as specified in the EWMH section 7.7 if (e.value_mask & (CWWidth | CWHeight)) { int w = (e.value_mask & CWWidth) ? e.width : _area.width(); int h = (e.value_mask & CWHeight) ? e.height : _area.height(); @@ -947,4 +992,26 @@ void OBClient::destroyHandler(const XDestroyWindowEvent &e) } +void OBClient::reparentHandler(const XReparentEvent &e) +{ + // this is when the client is first taken captive in the frame + if (e.parent == frame->plate()) return; + +#ifdef DEBUG + printf("ReparentNotify for 0x%lx\n", e.window); +#endif // DEBUG + + OtkEventHandler::reparentHandler(e); + + /* + This event is quite rare and is usually handled in unmapHandler. + However, if the window is unmapped when the reparent event occurs, + the window manager never sees it because an unmap event is not sent + to an already unmapped window. + */ + + // this deletes us etc + Openbox::instance->screen(_screen)->unmanageWindow(this); +} + }