mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
192 lines
6.1 KiB
C++
192 lines
6.1 KiB
C++
#include "Mwm.h"
|
|
#include "Frame.h"
|
|
#include "Winhints.h"
|
|
#include "Windowmanager.h"
|
|
|
|
void MWM::get_hints(Frame *f)
|
|
{
|
|
if(f->mwm_hints) {
|
|
XFree((char *)f->mwm_hints);
|
|
f->mwm_hints = 0;
|
|
}
|
|
|
|
unsigned long n=0;
|
|
f->mwm_hints = (MwmHints *)getProperty(f->window(), _XATOM_MWM_HINTS, _XATOM_MWM_HINTS, &n);
|
|
|
|
if(n >= PROP_MWM_HINTS_ELEMENTS) {
|
|
// Fill in the default value for missing fields:
|
|
if(!(f->mwm_hints->flags & MWM_HINTS_FUNCTIONS))
|
|
f->mwm_hints->functions = MWM_FUNC_ALL;
|
|
if(!(f->mwm_hints->flags & MWM_HINTS_DECORATIONS))
|
|
f->mwm_hints->decorations = MWM_DECOR_ALL;
|
|
} else {
|
|
XFree((char *)f->mwm_hints);
|
|
f->mwm_hints = 0;
|
|
}
|
|
}
|
|
|
|
static long mwm_functions(MwmHints *hints, XSizeHints *sh)
|
|
{
|
|
long functions = ~0U;
|
|
|
|
if(hints && (hints->flags & MWM_HINTS_FUNCTIONS))
|
|
{
|
|
if(hints->functions & MWM_FUNC_ALL)
|
|
functions = ~hints->functions;
|
|
else
|
|
functions = hints->functions;
|
|
|
|
} else {
|
|
|
|
if(sh) {
|
|
bool minmax = false;
|
|
if(sh->min_width == sh->max_width && sh->min_height == sh->max_height) {
|
|
functions &= ~MWM_FUNC_RESIZE;
|
|
minmax = true;
|
|
}
|
|
if((minmax && !(sh->flags & PResizeInc)) ||
|
|
(sh->width_inc == 0 && sh->height_inc == 0))
|
|
functions &= ~MWM_FUNC_MAXIMIZE;
|
|
}
|
|
}
|
|
functions &= (MWM_FUNC_RESIZE | MWM_FUNC_MOVE |
|
|
MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE |
|
|
MWM_FUNC_CLOSE);
|
|
return functions;
|
|
}
|
|
|
|
static long mwm_decors(MwmHints *hints, XSizeHints *sh)
|
|
{
|
|
long decors = ~0U;
|
|
long func = mwm_functions(hints, sh);
|
|
|
|
if(hints && (hints->flags & MWM_HINTS_DECORATIONS)) {
|
|
if(hints->decorations & MWM_DECOR_ALL)
|
|
decors = ~hints->decorations;
|
|
else
|
|
decors = hints->decorations;
|
|
|
|
} else {
|
|
|
|
if(sh) {
|
|
bool minmax = false;
|
|
if(sh->min_width == sh->max_width && sh->min_height == sh->max_height) {
|
|
decors &= ~MWM_DECOR_RESIZEH;
|
|
minmax = true;
|
|
}
|
|
if((minmax && !(sh->flags & PResizeInc)) ||
|
|
(sh->width_inc == 0 && sh->height_inc == 0))
|
|
decors &= ~MWM_DECOR_MAXIMIZE;
|
|
}
|
|
}
|
|
decors &= (MWM_DECOR_BORDER | MWM_DECOR_RESIZEH |
|
|
MWM_DECOR_TITLE | MWM_DECOR_MENU |
|
|
MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE);
|
|
|
|
// Add disabled buttons !!!
|
|
decors &=
|
|
~(/*((func & MWM_FUNC_RESIZE) ? 0 : MWM_DECOR_RESIZEH) |*/
|
|
((func & MWM_FUNC_MINIMIZE) ? 0 : MWM_DECOR_MINIMIZE) |
|
|
((func & MWM_FUNC_MAXIMIZE) ? 0 : MWM_DECOR_MAXIMIZE));
|
|
|
|
return decors;
|
|
}
|
|
|
|
bool MWM::update_hints(Frame *f)
|
|
{
|
|
MwmHints *mwm_hints = f->mwm_hints;
|
|
XSizeHints *size_hints = f->size_hints;
|
|
|
|
long decors = mwm_decors(mwm_hints, size_hints);
|
|
long functions = mwm_functions(mwm_hints, size_hints);
|
|
|
|
bool funcs_only = (mwm_hints &&
|
|
(mwm_hints->flags & (MWM_HINTS_FUNCTIONS) == MWM_HINTS_FUNCTIONS) &&
|
|
(mwm_hints->flags & (MWM_HINTS_DECORATIONS) != MWM_HINTS_DECORATIONS)
|
|
);
|
|
|
|
// The low bit means "turn the marked items off", invert this.
|
|
// Transient windows already have size & iconize buttons turned off:
|
|
if(functions & MWM_FUNC_ALL)
|
|
functions = ~functions & (f->transient_for_xid ? ~0x58 : -1);
|
|
if(decors & MWM_DECOR_ALL)
|
|
decors = ~decors & (f->transient_for_xid ? ~0x60 : -1);
|
|
|
|
int old_decor_flags = f->decor_flags();
|
|
int old_func_flags = f->func_flags();
|
|
int old_frame_flags = f->frame_flags();
|
|
|
|
// Get decorations
|
|
f->clear_decor_flags();
|
|
if(decors & MWM_DECOR_BORDER)
|
|
f->set_decor_flag(BORDER);
|
|
if(decors & MWM_DECOR_TITLE)
|
|
f->set_decor_flag(TITLEBAR);
|
|
if(decors & MWM_DECOR_MENU)
|
|
f->set_decor_flag(SYSMENU);
|
|
if(decors & MWM_DECOR_MINIMIZE)
|
|
f->set_decor_flag(MINIMIZE);
|
|
if(decors & MWM_DECOR_MAXIMIZE)
|
|
f->set_decor_flag(MAXIMIZE);
|
|
if(decors & MWM_DECOR_RESIZEH)
|
|
f->set_decor_flag(RESIZE);
|
|
|
|
// Get functions
|
|
f->clear_func_flags();
|
|
if(functions & MWM_FUNC_RESIZE) {
|
|
f->set_func_flag(RESIZE);
|
|
if(funcs_only) f->set_decor_flag(RESIZE|BORDER);
|
|
}
|
|
if(functions & MWM_FUNC_MOVE) {
|
|
f->set_func_flag(MOVE);
|
|
if(funcs_only) f->set_decor_flag(BORDER);
|
|
}
|
|
if(functions & MWM_FUNC_MINIMIZE) {
|
|
f->set_func_flag(MINIMIZE);
|
|
if(funcs_only) f->set_decor_flag(MINIMIZE);
|
|
}
|
|
if(functions & MWM_FUNC_MAXIMIZE) {
|
|
f->set_func_flag(MAXIMIZE);
|
|
if(funcs_only) f->set_decor_flag(MAXIMIZE);
|
|
}
|
|
if(functions & MWM_FUNC_CLOSE) {
|
|
f->set_func_flag(CLOSE);
|
|
f->set_decor_flag(CLOSE);
|
|
}
|
|
|
|
// some Motif programs use this to disable resize :-(
|
|
// and some programs change this after the window is shown (*&%$#%)
|
|
if(!(functions & MWM_FUNC_RESIZE) || !(decors & MWM_DECOR_RESIZEH))
|
|
f->clear_decor_flag(RESIZE);
|
|
else
|
|
f->set_decor_flag(RESIZE);
|
|
|
|
// and some use this to disable the Close function. The commented
|
|
// out test is it trying to turn off the mwm menu button: it appears
|
|
// programs that do that still expect Alt+F4 to close them, so I
|
|
// leave the close on then:
|
|
if (!(functions & 0x20) /*|| !(prop[2]&0x10)*/) {
|
|
f->clear_func_flag(CLOSE);
|
|
f->clear_decor_flag(CLOSE);
|
|
} else {
|
|
f->set_func_flag(CLOSE);
|
|
f->set_decor_flag(CLOSE);
|
|
}
|
|
|
|
// Set modal
|
|
if(!f->shown() && mwm_hints && (mwm_hints->flags & MWM_HINTS_INPUT_MODE) && (mwm_hints->input_mode != MWM_INPUT_MODELESS))
|
|
f->set_frame_flag(MODAL);
|
|
|
|
return ((f->frame_flags() ^ old_frame_flags) || (f->decor_flags() ^ old_decor_flags) || (f->func_flags() ^ old_func_flags));
|
|
}
|
|
|
|
void MWM::set_motif_info()
|
|
{
|
|
MotifWmInfo mwminfo;
|
|
mwminfo.flags = MWM_INFO_STARTUP_CUSTOM;
|
|
mwminfo.wm_window = root_win;
|
|
XChangeProperty(fl_display, root_win, _XATOM_MOTIF_WM_INFO, _XATOM_MOTIF_WM_INFO,
|
|
32, PropModeReplace,
|
|
(unsigned char *)&mwminfo, 2);
|
|
}
|