How do I disable the Minimize, Maximize and Close buttons
from my application's Window?
|
19-Dec-00 14:00 GMT
|
Question: I want to disable the Minimize, Maximize and Close
buttons from my application's Window. How can I do that?
This can be done, but the code to do it will partly be window manager specific.
Under the assumption that you are running a Motif-compliant window manager
(Mwm, CDE dtwm, etc), then the task is performed in two stages.
Firstly, the window manager decorations are controlled through the
XmNmwmDecorations resource of the shell. This is a mask formed by
combining the following values:
#include <Xm/MwmUtil.h>
MWM_DECOR_ALL
MWM_DECOR_BORDER
MWM_DECOR_MINIMIZE
MWM_DECOR_MAXIMIZE
MWM_DECOR_TITLE
MWM_DECOR_MENU
MWM_DECOR_RESIZEH
For example, to remove the maximize and minimize buttons, the following code will do the trick:
extern Widget shell;
XtVaSetValues (shell,
XmNmwmDecorations,
MWM_DECOR_ALL | MWM_DECOR_MAXIMIZE | MWM_DECOR_MINIMIZE,
NULL);
Secondly, the contents of the menu is controlled through the
XmNmwmFunctions resource of the shell. This is also a mask,
formed from the following values:
#include <Xm/MwmUtil.h>
MWM_FUNC_ALL
MWM_FUNC_RESIZE
MWM_FUNC_MOVE
MWM_FUNC_MINIMIZE
MWM_FUNC_MAXIMIZE
MWM_FUNC_CLOSE
For example, the following code removes the Close option from the menu:
extern Widget shell;
XtVaSetValues (shell,
XmNmwmFunctions,
MWM_FUNC_ALL | MWM_FUNC_CLOSE,
NULL);
Note that in the specified question requirements, you probably also want to
remove the menu maximize/minimize options for consistency, otherwise the user
can still maximize/minimize the application using the menu options, even
though you have removed the window manager decoration buttons. The following code
also removes the maximize, minimize menu entries:
extern Widget shell;
XtVaSetValues (shell,
XmNmwmFunctions,
MWM_FUNC_ALL | MWM_FUNC_CLOSE |
MWM_FUNC_MAXIMIZE | MWM_FUNC_MINIMIZE,
NULL);
Certain Mwm decorations/menu items which you may want
to configure at the shell might get overridden by a BulletinBoard
child, particularly if the BulletinBoard has XmNnoResize set to True.
The Resize menu entry is affected by this. The specific requirements
here however should not be affected.
If you are running another non-Mwm compliant window manager, you
will need to get hold of the documentation for the window manager
concerned. This time, you will probably need to set X resources for your
application rather than performing the changes in code via shell resources,
although you can write window-manager specific code if you are prepared to
play round with code which directly manipulates Window Properties.
Further, all sorts of shell resources in general might have little effect,
depending on the level of ICCCM compliance for the window manager concerned.
You should be aware that certain things are implemented in terms of hints
to the window manager: the manager is free to accept, ignore, or modify the
request in whatever way it sees fit in keeping with its general layout/stacking/decoration
policies. This is particularly true of certain resources for the shell widgets.
Indeed, although some shell resources are normal hints which any ICCCM-compliant
window manager should implement, there are also window manager-specific hints which
only the window manager concerned knows how to interpret.
In the given example, I would be inclined to also intercept the Close operation
from the window manager, just in case the request to remove the menu entry fails to
have the desired effect. The following routine installs a callback which will be invoked
when the user uses the window manager Close menu entry:
/* Install a Window Manager Close Callback */
#include <Xm/Xm.h>
#ifndef _NO_PROTO
Boolean WM_set_close_callback(Widget shell,
void (*callback)(Widget, XtPointer, XtPointer),
XtPointer client_data)
#else /* _NO_PROTO */
Boolean WM_set_close_callback(shell, callback, client_data)
Widget shell ;
void (*callback)() ;
XtPointer client_data ;
#endif /* _NO_PROTO */
{
#ifndef _NO_PROTO
extern Atom XmInternAtom(Display *, char *, Boolean) ;
#else /* _NO_PROTO */
extern Atom XmInternAtom() ;
#endif /* _NO_PROTO */
Display *display = (Display *) 0 ;
Atom property = (Atom) 0 ;
Atom protocol = (Atom) 0 ;
if (shell == (Widget) 0) {
return False ;
}
if ((display = XtDisplay(shell)) == (Display *) 0) {
return False ;
}
/* Retrieve Window Manager Protocol Property */
if ((property = XmInternAtom(display,
"WM_PROTOCOLS",
False)) == (Atom) 0) {
return False ;
}
/* Retrieve Window Manager Delete Window Property */
if ((protocol = XmInternAtom(display,
"WM_DELETE_WINDOW",
True)) == (Atom) 0) {
return False ;
}
/* Ensure that Shell has the Delete Window Property */
/* NB: Necessary since some Window managers are not */
/* Fully XWM Compilant (olwm for instance is not) */
XmAddProtocols(shell, property, &protocol, 1) ;
/* Now add our callback into the Protocol Callback List */
XmAddProtocolCallback(shell,
property,
protocol,
callback,
client_data) ;
return True ;
}
What the callback does is application -specific, but if all that you want is
to stop the window manager menu having effect, then the callback can do
precisely nothing.
Lastly, I would also make sure that the XmNdeleteResponse for the shell was
appropriately set. That is, the value XmDESTROY might be dangerous
to the application, so I would consider changing this to XmDO_NOTHING
or XmUNMAP depending on the effect I required. This will prevent the
window manager from destroying our dialog in response to a rogue Close
request: the application remains in control of this critical operation.
Sponsored
by X-Designer - The Leading X/Motif GUI Builder
- Click to download a FREE evaluation
Goto top of page
|