support for the Mwm Hints
Dana Jansens danakj@orodu.net
2 files changed,
114 insertions(+),
6 deletions(-)
M
src/client.cc
→
src/client.cc
@@ -27,10 +27,13 @@ // update EVERYTHING the first time!!
// the state is kinda assumed to be normal. is this right? XXX _wmstate = NormalState; + // no default decors or functions, each has to be enabled + _decorations = _functions = 0; getArea(); getDesktop(); getType(); + getMwmHints(); getState(); getShaped();@@ -168,6 +171,67 @@ // _type = Type_Dialog;
//else _type = Type_Normal; } + + // set the decorations and functions based on the type of the window +} + + +void OBClient::getMWMHints() +{ + const otk::OBProperty *property = Openbox::instance->property(); + + unsigned long num; + MwmHints *hints; + + 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; + } + + // retrieved the hints + // Mwm Hints are applied subtractively to what has already been chosen for + // decor and functionality + + if (hints->flags & MwmDecorations) { + if (! (hints->decorations & MwmDecor_All)) { + if (! (hints->decorations & MwmDecor_Border)) + _decorations &= ~Decor_Border; + if (! (hints->decorations & MwmDecor_Handle)) + _decorations &= ~Decor_Handle; + if (! (hints->decorations & MwmDecor_Title)) + _decorations &= ~Decor_Titlebar; + if (! (hints->decorations & MwmDecor_Iconify)) + _decorations &= ~Decor_Iconify; + if (! (hints->decorations & MwmDecor_Maximize)) + _decorations &= ~Decor_Maximize; + } + } + + _mwm_functions = 0xffffffff; // everything! + + if (hints->flags & MwmFunctions) { + if (! (hints->functions & MwmFunc_All)) { + _mwm_functions = hints->functions; + + if (! (hints->functions & MwmFunc_Resize)) + functions &= ~Func_Resize; + if (! (hints->functions & MwmFunc_Move)) + functions &= ~Func_Move; + if (! (hints->functions & MwmFunc_Iconify)) + functions &= ~Func_Iconify; + if (! (hints->functions & MwmFunc_Maximize)) + functions &= ~Func_Maximize; + if (! (hints->functions & MwmFunc_Close)) + functions &= ~Func_Close; + } + } + delete [] hints; }@@ -229,7 +293,8 @@ #endif // SHAPE
} -void OBClient::updateProtocols() { +void OBClient::updateProtocols() +{ const otk::OBProperty *property = Openbox::instance->property(); Atom *proto;@@ -240,8 +305,13 @@
if (XGetWMProtocols(otk::OBDisplay::display, _window, &proto, &num_return)) { for (int i = 0; i < num_return; ++i) { if (proto[i] == property->atom(otk::OBProperty::wm_delete_window)) { - // XXX: do shit with this! let the window close, and show a close - // button + // add the close button/functionality only if the mwm hints didnt + // exclude it + if (_mwm_functions & MwmFunc_Close) { + decorations |= Decor_Close; + functions |= Func_Close; + // XXX: update the decor? + } } else if (proto[i] == property->atom(otk::OBProperty::wm_take_focus)) // if this protocol is requested, then the window will be notified // by the window manager whenever it receives focus@@ -263,6 +333,9 @@ _inc_x = _inc_y = 1;
_base_x = _base_y = 0; _min_x = _min_y = 0; _max_x = _max_y = INT_MAX; + + // XXX: might want to cancel any interactive resizing of the window at this + // point.. // get the hints from the window if (XGetWMNormalHints(otk::OBDisplay::display, _window, &size, &ret)) {
M
src/client.hh
→
src/client.hh
@@ -29,8 +29,8 @@ Type_Splash,
Type_Dialog, Type_Normal }; - enum MwmFlags { Functions = 1 << 0, - Decorations = 1 << 1 }; + enum MwmFlags { MwmFunctions = 1 << 0, + MwmDecorations = 1 << 1 }; enum MwmFunctions { MwmFunc_All = 1 << 0, MwmFunc_Resize = 1 << 1,@@ -46,6 +46,23 @@ MemDecor_Title = 1 << 3,
//MemDecor_Menu = 1 << 4, MemDecor_Iconify = 1 << 5, MemDecor_Maximize = 1 << 6 }; + + // the things the user can do to the client window + enum Function { Func_Resize = 1 << 0, + Func_Move = 1 << 1, + Func_Iconify = 1 << 2, + Func_Maximize = 1 << 3, + Func_Close = 1 << 4 }; + typedef unsigned char FunctionFlags; + + // the decorations the client window wants to be displayed on it + enum Decoration { Decor_Titlebar = 1 << 0, + Decor_Handle = 1 << 1, + Decor_Border = 1 << 2, + Decor_Iconify = 1 << 3, + Decor_Maximize = 1 << 4, + Decor_Close = 1 << 5 }; + typedef unsigned char DecorationFlags; // this structure only contains 3 elements... the Motif 2.0 structure // contains 5... we only need the first 3... so that is all we will define@@ -140,10 +157,26 @@ bool _fullscreen;
//! The window should be on top of other windows of the same type bool _floating; - // XXX: motif decoration hints! + //! A bitmask of values in the OBClient::Decoration enum + /*! + The values in the variable are the decorations that the client wants to be + displayed around it. + */ + DecorationFlags _decorations; + + //! The functions requested by the Mwm Hints + int _mwm_functions; + + //! A bitmask of values in the OBClient::Function enum + /*! + The values in the variable specify the ways in which the user is allowed to + modify this window. + */ + FunctionFlags _functions; void getDesktop(); void getType(); + void getMwmHints(); void getArea(); void getState(); void getShaped();@@ -177,6 +210,8 @@ inline bool focusNotify() const { return _focus_notify; }
inline bool shaped() const { return _shaped; } inline int gravity() const { return _gravity; } inline bool positionRequested() const { return _positioned; } + inline DecorationFlags decorations() const { return _decorations; } + inline FunctionFlags funtions() const { return _functions; } // states inline bool modal() const { return _modal; }