From 9dc76e1bace5ca5190e25a50a098739aaecc6ccf Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 6 Nov 2002 11:31:50 +0000 Subject: [PATCH] support for the Mwm Hints --- src/client.cc | 79 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/client.hh | 41 ++++++++++++++++++++++++-- 2 files changed, 114 insertions(+), 6 deletions(-) diff --git a/src/client.cc b/src/client.cc index 5ecbb9ae..f391746c 100644 --- a/src/client.cc +++ b/src/client.cc @@ -27,10 +27,13 @@ OBClient::OBClient(Window window) // 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 @@ void OBClient::getType() //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 @@ void OBClient::getShaped() } -void OBClient::updateProtocols() { +void OBClient::updateProtocols() +{ const otk::OBProperty *property = Openbox::instance->property(); Atom *proto; @@ -240,8 +305,13 @@ void OBClient::updateProtocols() { 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 @@ -264,6 +334,9 @@ void OBClient::updateNormalHints() _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)) { _positioned = (size.flags & (PPosition|USPosition)); diff --git a/src/client.hh b/src/client.hh index b0e537fd..7e864744 100644 --- a/src/client.hh +++ b/src/client.hh @@ -29,8 +29,8 @@ public: 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, @@ -47,6 +47,23 @@ public: 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 typedef struct MwmHints { @@ -140,10 +157,26 @@ private: //! 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 @@ public: 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; } -- 2.45.2