all repos — openbox @ a93f06f5b3162e59c04074a14bd3702e4bb82133

openbox fork - make it a bit more like ryudo

keep track of transients. however not group transients yet
Dana Jansens danakj@orodu.net
commit

a93f06f5b3162e59c04074a14bd3702e4bb82133

parent

c7b22b4f9cee63d860ad4f6617cd5210299b9d8b

2 files changed, 116 insertions(+), 89 deletions(-)

jump to
M src/client.ccsrc/client.cc

@@ -46,44 +46,13 @@ _transient_for = 0;

getArea(); getDesktop(); + updateTransientFor(); getType(); - - // XXX: changeAllowedActions(); - - // set the decorations and functions - _decorations = Decor_Titlebar | Decor_Handle | Decor_Border | - Decor_Iconify | Decor_Maximize; - _functions = Func_Resize | Func_Move | Func_Iconify | Func_Maximize; - switch (_type) { - case Type_Normal: - // normal windows retain all of the possible decorations and - // functionality - - case Type_Dialog: - // dialogs cannot be maximized - _decorations &= ~Decor_Maximize; - _functions &= ~Func_Maximize; - break; - - case Type_Menu: - case Type_Toolbar: - case Type_Utility: - // these windows get less functionality - _decorations &= ~(Decor_Iconify | Decor_Handle); - _functions &= ~(Func_Iconify | Func_Resize); - break; + getMwmHints(); - case Type_Desktop: - case Type_Dock: - case Type_Splash: - // none of these windows are manipulated by the window manager - _decorations = 0; - _functions = 0; - break; - } + setupDecorAndFunctions(); - getMwmHints(); // this fucks (in good ways) with the decors and functions getState(); getShaped();

@@ -95,7 +64,6 @@ updateIconTitle();

updateClass(); updateStrut(); - calcLayer(); changeState(); }

@@ -183,57 +151,99 @@ }

} -void OBClient::getMwmHints() +void OBClient::setupDecorAndFunctions() { - const otk::OBProperty *property = Openbox::instance->property(); + // start with everything + _decorations = Decor_Titlebar | Decor_Handle | Decor_Border | + Decor_Iconify | Decor_Maximize; + _functions = Func_Resize | Func_Move | Func_Iconify | Func_Maximize; + + switch (_type) { + case Type_Normal: + // normal windows retain all of the possible decorations and + // functionality - unsigned long num; - MwmHints *hints; + case Type_Dialog: + // dialogs cannot be maximized + _decorations &= ~Decor_Maximize; + _functions &= ~Func_Maximize; + break; - num = MwmHints::elements; - if (!property->get(_window, otk::OBProperty::motif_wm_hints, - otk::OBProperty::motif_wm_hints, &num, - (unsigned long **)&hints)) - return; - - if (num < MwmHints::elements) { - delete [] hints; - return; + case Type_Menu: + case Type_Toolbar: + case Type_Utility: + // these windows get less functionality + _decorations &= ~(Decor_Iconify | Decor_Handle); + _functions &= ~(Func_Iconify | Func_Resize); + break; + + case Type_Desktop: + case Type_Dock: + case Type_Splash: + // none of these windows are manipulated by the window manager + _decorations = 0; + _functions = 0; + break; } - // retrieved the hints // Mwm Hints are applied subtractively to what has already been chosen for // decor and functionality - - if (hints->flags & MwmFlag_Decorations) { - if (! (hints->decorations & MwmDecor_All)) { - if (! (hints->decorations & MwmDecor_Border)) + if (_mwmhints.flags & MwmFlag_Decorations) { + if (! (_mwmhints.decorations & MwmDecor_All)) { + if (! (_mwmhints.decorations & MwmDecor_Border)) _decorations &= ~Decor_Border; - if (! (hints->decorations & MwmDecor_Handle)) + if (! (_mwmhints.decorations & MwmDecor_Handle)) _decorations &= ~Decor_Handle; - if (! (hints->decorations & MwmDecor_Title)) + if (! (_mwmhints.decorations & MwmDecor_Title)) _decorations &= ~Decor_Titlebar; - if (! (hints->decorations & MwmDecor_Iconify)) + if (! (_mwmhints.decorations & MwmDecor_Iconify)) _decorations &= ~Decor_Iconify; - if (! (hints->decorations & MwmDecor_Maximize)) + if (! (_mwmhints.decorations & MwmDecor_Maximize)) _decorations &= ~Decor_Maximize; } } - if (hints->flags & MwmFlag_Functions) { - if (! (hints->functions & MwmFunc_All)) { - if (! (hints->functions & MwmFunc_Resize)) + if (_mwmhints.flags & MwmFlag_Functions) { + if (! (_mwmhints.functions & MwmFunc_All)) { + if (! (_mwmhints.functions & MwmFunc_Resize)) _functions &= ~Func_Resize; - if (! (hints->functions & MwmFunc_Move)) + if (! (_mwmhints.functions & MwmFunc_Move)) _functions &= ~Func_Move; - if (! (hints->functions & MwmFunc_Iconify)) + if (! (_mwmhints.functions & MwmFunc_Iconify)) _functions &= ~Func_Iconify; - if (! (hints->functions & MwmFunc_Maximize)) + if (! (_mwmhints.functions & MwmFunc_Maximize)) _functions &= ~Func_Maximize; - //if (! (hints->functions & MwmFunc_Close)) + // dont let mwm hints kill the close button + //if (! (_mwmhints.functions & MwmFunc_Close)) // _functions &= ~Func_Close; } } + + // XXX: changeAllowedActions(); +} + + +void OBClient::getMwmHints() +{ + const otk::OBProperty *property = Openbox::instance->property(); + + unsigned long num = MwmHints::elements; + unsigned long *hints; + + _mwmhints.flags = 0; // default to none + + if (!property->get(_window, otk::OBProperty::motif_wm_hints, + otk::OBProperty::motif_wm_hints, &num, + (unsigned long **)&hints)) + return; + + if (num == MwmHints::elements) { + // retrieved the hints + _mwmhints.flags = hints[0]; + _mwmhints.functions = hints[1]; + _mwmhints.decorations = hints[2]; + } + delete [] hints; }

@@ -318,16 +328,29 @@ }

void OBClient::calcLayer() { - if (_iconic) _layer = Layer_Icon; - else if (_fullscreen) _layer = Layer_Fullscreen; - else if (_type == Type_Desktop) _layer = Layer_Desktop; + StackLayer l; + + if (_iconic) l = Layer_Icon; + else if (_fullscreen) l = Layer_Fullscreen; + else if (_type == Type_Desktop) l = Layer_Desktop; else if (_type == Type_Dock) { - if (!_below) _layer = Layer_Top; - else _layer = Layer_Normal; + if (!_below) l = Layer_Top; + else l = Layer_Normal; + } + else if (_above) l = Layer_Above; + else if (_below) l = Layer_Below; + else l = Layer_Normal; + + if (l != _layer) { + _layer = l; + if (frame) { + /* + if we don't have a frame, then we aren't mapped yet (and this would + SIGSEGV :) + */ + Openbox::instance->screen(_screen)->restack(true, this); // raise + } } - else if (_above) _layer = Layer_Above; - else if (_below) _layer = Layer_Below; - else _layer = Layer_Normal; }

@@ -580,8 +603,12 @@ if (e.atom == XA_WM_NORMAL_HINTS)

updateNormalHints(); else if (e.atom == XA_WM_HINTS) updateWMHints(); - else if (e.atom == XA_WM_TRANSIENT_FOR) + else if (e.atom == XA_WM_TRANSIENT_FOR) { updateTransientFor(); + getType(); + calcLayer(); // type may have changed, so update the layer + setupDecorAndFunctions(); + } else if (e.atom == property->atom(otk::OBProperty::net_wm_name) || e.atom == property->atom(otk::OBProperty::wm_name)) updateTitle();

@@ -627,7 +654,7 @@

void OBClient::setState(StateAction action, long data1, long data2) { const otk::OBProperty *property = Openbox::instance->property(); - bool restack = false, shadestate = _shaded; + bool shadestate = _shaded; if (!(action == State_Add || action == State_Remove || action == State_Toggle))

@@ -695,17 +722,14 @@ } else if (state ==

property->atom(otk::OBProperty::net_wm_state_fullscreen)) { if (_fullscreen) continue; _fullscreen = true; - restack = false; } else if (state == property->atom(otk::OBProperty::net_wm_state_above)) { if (_above) continue; _above = true; - restack = true; } else if (state == property->atom(otk::OBProperty::net_wm_state_below)) { if (_below) continue; _below = true; - restack = true; } } else { // action == State_Remove

@@ -737,26 +761,20 @@ } else if (state ==

property->atom(otk::OBProperty::net_wm_state_fullscreen)) { if (!_fullscreen) continue; _fullscreen = false; - restack = true; } else if (state == property->atom(otk::OBProperty::net_wm_state_above)) { if (!_above) continue; _above = false; - restack = true; } else if (state == property->atom(otk::OBProperty::net_wm_state_below)) { if (!_below) continue; _below = false; - restack = true; } } } if (shadestate != _shaded) shade(shadestate); - if (restack) { - calcLayer(); - Openbox::instance->screen(_screen)->restack(true, this); // raise - } + calcLayer(); }

@@ -1011,7 +1029,8 @@ if (_below)

netstate[num++] = property->atom(otk::OBProperty::net_wm_state_below); property->set(_window, otk::OBProperty::net_wm_state, otk::OBProperty::Atom_Atom, netstate, num); - + + calcLayer(); }

@@ -1027,8 +1046,6 @@ _above = false;

_below = true; // below } changeState(); - calcLayer(); - Openbox::instance->screen(_screen)->restack(true, this); // raise }
M src/client.hhsrc/client.hh

@@ -34,11 +34,11 @@ This structure only contains 3 elements, even though the Motif 2.0

structure contains 5. We only use the first 3, so that is all gets defined. */ struct MwmHints { - //! The number of elements in the OBClient::MwmHints struct - static const unsigned int elements = 3; unsigned long flags; //!< A bitmask of OBClient::MwmFlags values unsigned long functions; //!< A bitmask of OBClient::MwmFunctions values unsigned long decorations;//!< A bitmask of OBClient::MwmDecorations values + //! The number of elements in the OBClient::MwmHints struct + static const unsigned int elements = 3; }; //! Maintains the state of a client window.

@@ -246,6 +246,9 @@ displaying its size to the user, or working with its min/max size

*/ otk::Point _base_size; + //! Window decoration and functionality hints + MwmHints _mwmhints; + //! Where to place the decorated window in relation to the undecorated window int _gravity;

@@ -323,6 +326,13 @@ //! Determines if the window uses the Shape extension and sets

//! OBClient::_shaped void getShaped(); + //! Set up what decor should be shown on the window and what functions should + //! be allowed (OBClient::_decorations and OBClient::_functions). + /*! + This also updates the NET_WM_ALLOWED_ACTIONS hint. + */ + void setupDecorAndFunctions(); + //! Sets the wm_state to the specified value void setWMState(long state); //! Sends the window to the specified desktop