summaryrefslogtreecommitdiffstats
path: root/src/kernel
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-01-26 16:34:00 -0600
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-01-26 16:34:00 -0600
commit0eb9f5e217225129b22de1a48fe7300723456da3 (patch)
treeede5a4dd39476960a1f113a323b34b613cf07987 /src/kernel
parent336d563830cd5f9f1f9abdce20db839d06431168 (diff)
downloadqt3-0eb9f5e217225129b22de1a48fe7300723456da3.tar.gz
qt3-0eb9f5e217225129b22de1a48fe7300723456da3.zip
Add NetWM/Motif controls to QWidget
This must break binary compatibility, so version was also bumped to 3.4.0
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/qapplication_x11.cpp34
-rw-r--r--src/kernel/qnamespace.h22
-rw-r--r--src/kernel/qwidget.cpp20
-rw-r--r--src/kernel/qwidget.h48
-rw-r--r--src/kernel/qwidget_x11.cpp79
5 files changed, 185 insertions, 18 deletions
diff --git a/src/kernel/qapplication_x11.cpp b/src/kernel/qapplication_x11.cpp
index 7bc9f48..45d83df 100644
--- a/src/kernel/qapplication_x11.cpp
+++ b/src/kernel/qapplication_x11.cpp
@@ -262,9 +262,22 @@ Atom qt_net_wm_state = 0;
Atom qt_net_wm_state_modal = 0;
Atom qt_net_wm_state_max_v = 0;
Atom qt_net_wm_state_max_h = 0;
-Atom qt_net_wm_state_fullscreen = 0;
-Atom qt_net_wm_state_above = 0;
-Atom qt_net_wm_window_type = 0;
+Atom qt_net_wm_state_fullscreen = 0;
+Atom qt_net_wm_state_above = 0;
+Atom qt_net_wm_action = 0;
+Atom qt_net_wm_action_move = 0;
+Atom qt_net_wm_action_resize = 0;
+Atom qt_net_wm_action_minimize = 0;
+Atom qt_net_wm_action_shade = 0;
+Atom qt_net_wm_action_stick = 0;
+Atom qt_net_wm_action_max_h = 0;
+Atom qt_net_wm_action_max_v = 0;
+Atom qt_net_wm_action_fullscreen = 0;
+Atom qt_net_wm_action_change_desktop = 0;
+Atom qt_net_wm_action_close = 0;
+Atom qt_net_wm_action_above = 0;
+Atom qt_net_wm_action_below = 0;
+Atom qt_net_wm_window_type = 0;
Atom qt_net_wm_window_type_normal = 0;
Atom qt_net_wm_window_type_dialog = 0;
Atom qt_net_wm_window_type_toolbar = 0;
@@ -2003,6 +2016,19 @@ void qt_init_internal( int *argcptr, char **argv,
qt_x11_intern_atom( "_NET_WM_STATE_MAXIMIZED_HORZ", &qt_net_wm_state_max_h );
qt_x11_intern_atom( "_NET_WM_STATE_FULLSCREEN", &qt_net_wm_state_fullscreen );
qt_x11_intern_atom( "_NET_WM_STATE_ABOVE", &qt_net_wm_state_above );
+ qt_x11_intern_atom( "_NET_WM_ALLOWED_ACTIONS", &qt_net_wm_action );
+ qt_x11_intern_atom( "_NET_WM_ACTION_MOVE", &qt_net_wm_action_move );
+ qt_x11_intern_atom( "_NET_WM_ACTION_RESIZE", &qt_net_wm_action_resize );
+ qt_x11_intern_atom( "_NET_WM_ACTION_MINIMIZE", &qt_net_wm_action_minimize );
+ qt_x11_intern_atom( "_NET_WM_ACTION_SHADE", &qt_net_wm_action_shade );
+ qt_x11_intern_atom( "_NET_WM_ACTION_STICK", &qt_net_wm_action_stick );
+ qt_x11_intern_atom( "_NET_WM_ACTION_MAXIMIZE_HORZ", &qt_net_wm_action_max_h );
+ qt_x11_intern_atom( "_NET_WM_ACTION_MAXIMIZE_VERT", &qt_net_wm_action_max_v );
+ qt_x11_intern_atom( "_NET_WM_ACTION_FULLSCREEN", &qt_net_wm_action_fullscreen );
+ qt_x11_intern_atom( "_NET_WM_ACTION_CHANGE_DESKTOP", &qt_net_wm_action_change_desktop );
+ qt_x11_intern_atom( "_NET_WM_ACTION_CLOSE", &qt_net_wm_action_close );
+ qt_x11_intern_atom( "_NET_WM_ACTION_ABOVE", &qt_net_wm_action_above );
+ qt_x11_intern_atom( "_NET_WM_ACTION_BELOW", &qt_net_wm_action_below );
qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE", &qt_net_wm_window_type );
qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_NORMAL", &qt_net_wm_window_type_normal );
qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_DIALOG", &qt_net_wm_window_type_dialog );
@@ -5167,7 +5193,7 @@ bool QETWidget::translateKeyEventInternal( const XEvent *event, int& count,
uint keystate = event->xkey.state;
// remove the modifiers where mode_switch exists... HPUX machines seem
// to have alt *AND* mode_switch both in Mod1Mask, which causes
- // XLookupString to return things like 'å' (aring) for ALT-A. This
+ // XLookupString to return things like '�' (aring) for ALT-A. This
// completely breaks modifiers. If we remove the modifier for Mode_switch,
// then things work correctly...
xkeyevent.state &= ~qt_mode_switch_remove_mask;
diff --git a/src/kernel/qnamespace.h b/src/kernel/qnamespace.h
index 1598785..2201a3d 100644
--- a/src/kernel/qnamespace.h
+++ b/src/kernel/qnamespace.h
@@ -168,6 +168,28 @@ public:
WState_HasMouse = 0x00800000
};
+ // NetWM flags; documented in qwidget.cpp
+ typedef uint NFlags;
+
+ // documented in qwidget.cpp
+ enum NETWMFlags {
+#if defined(Q_WS_X11)
+ WX11DisableMove = 0x00000001,
+ WX11DisableClose = 0x00000002,
+ WX11DisableResize = 0x00000004,
+ WX11DisableMinimize = 0x00000008,
+ WX11DisableMaximize = 0x00000010,
+ WX11DisableShade = 0x00000020
+#else
+ WX11DisableMove = 0x00000000,
+ WX11DisableClose = 0x00000000,
+ WX11DisableResize = 0x00000000,
+ WX11DisableMinimize = 0x00000000,
+ WX11DisableMaximize = 0x00000000,
+ WX11DisableShade = 0x00000000
+#endif
+ };
+
// Widget flags2; documented in qwidget.cpp
typedef uint WFlags;
diff --git a/src/kernel/qwidget.cpp b/src/kernel/qwidget.cpp
index 856907c..65aabb4 100644
--- a/src/kernel/qwidget.cpp
+++ b/src/kernel/qwidget.cpp
@@ -776,6 +776,25 @@ QSize qt_naturalWidgetSize( QWidget *w ) {
*/
/*!
+ \enum Qt::NETWMFlags
+
+ \keyword NETWM flag
+
+ This enum type is used to specify various NETWM properties
+ under X11 and similar systems.
+
+ The main types are
+
+ \value WX11DisableMove
+ \value WX11DisableClose
+ \value WX11DisableResize
+ \value WX11DisableMinimize
+ \value WX11DisableMaximize
+ \value WX11DisableShade
+
+*/
+
+/*!
\enum Qt::WidgetState
Internal flags.
@@ -874,6 +893,7 @@ QWidget::QWidget( QWidget *parent, const char *name, WFlags f )
winid = 0; // default attributes
widget_state = 0;
widget_flags = f;
+ netwm_flags = 0;
focus_policy = 0;
own_font = 0;
own_palette = 0;
diff --git a/src/kernel/qwidget.h b/src/kernel/qwidget.h
index c83acb5..f77ca3a 100644
--- a/src/kernel/qwidget.h
+++ b/src/kernel/qwidget.h
@@ -455,6 +455,7 @@ public:
QWidget * parentWidget( bool sameWindow = FALSE ) const;
WState testWState( WState s ) const;
WFlags testWFlags( WFlags f ) const;
+ NFlags testNFlags( NFlags f ) const;
static QWidget * find( WId );
static QWidgetMapper *wmapper();
@@ -578,6 +579,9 @@ protected:
WFlags getWFlags() const;
virtual void setWFlags( WFlags );
void clearWFlags( WFlags n );
+ NFlags getNFlags() const;
+ virtual void setNFlags( NFlags );
+ void clearNFlags( NFlags n );
virtual bool focusNextPrevChild( bool next );
@@ -665,20 +669,25 @@ private:
void setBackgroundX11Relative();
#endif
- WId winid;
- uint widget_state;
- uint widget_flags;
- uint focus_policy : 4;
- uint own_font :1;
- uint own_palette :1;
- uint sizehint_forced :1;
- uint is_closing :1;
- uint in_show : 1;
- uint in_show_maximized : 1;
- uint fstrut_dirty : 1;
- uint im_enabled : 1;
- QRect crect;
- QColor bg_col;
+ WId winid;
+ uint widget_state;
+ uint widget_flags;
+ uint netwm_flags;
+ uint reserved_1;
+ uint reserved_2;
+ uint reserved_3;
+ uint reserved_4;
+ uint focus_policy : 4;
+ uint own_font :1;
+ uint own_palette :1;
+ uint sizehint_forced :1;
+ uint is_closing :1;
+ uint in_show : 1;
+ uint in_show_maximized : 1;
+ uint fstrut_dirty : 1;
+ uint im_enabled : 1;
+ QRect crect;
+ QColor bg_col;
#ifndef QT_NO_PALETTE
QPalette pal;
#endif
@@ -756,6 +765,8 @@ inline Qt::WState QWidget::testWState( WState s ) const
inline Qt::WFlags QWidget::testWFlags( WFlags f ) const
{ return (widget_flags & f); }
+inline Qt::NFlags QWidget::testNFlags( NFlags f ) const
+{ return (netwm_flags & f); }
inline WId QWidget::winId() const
{ return winid; }
@@ -916,12 +927,21 @@ inline void QWidget::clearWState( uint f )
inline Qt::WFlags QWidget::getWFlags() const
{ return widget_flags; }
+inline Qt::NFlags QWidget::getNFlags() const
+{ return netwm_flags; }
+
inline void QWidget::setWFlags( WFlags f )
{ widget_flags |= f; }
+inline void QWidget::setNFlags( NFlags f )
+{ netwm_flags |= f; }
+
inline void QWidget::clearWFlags( WFlags f )
{ widget_flags &= ~f; }
+inline void QWidget::clearNFlags( NFlags f )
+{ netwm_flags &= ~f; }
+
inline void QWidget::constPolish() const
{
if ( !testWState(WState_Polished) ) {
diff --git a/src/kernel/qwidget_x11.cpp b/src/kernel/qwidget_x11.cpp
index 02fdebf..775829c 100644
--- a/src/kernel/qwidget_x11.cpp
+++ b/src/kernel/qwidget_x11.cpp
@@ -124,6 +124,19 @@ extern Atom qt_net_wm_state_max_h;
extern Atom qt_net_wm_state_fullscreen;
extern Atom qt_net_wm_state_above;
extern Atom qt_net_wm_state_stays_on_top;
+extern Atom qt_net_wm_action;
+extern Atom qt_net_wm_action_move;
+extern Atom qt_net_wm_action_resize;
+extern Atom qt_net_wm_action_minimize;
+extern Atom qt_net_wm_action_shade;
+extern Atom qt_net_wm_action_stick;
+extern Atom qt_net_wm_action_max_h;
+extern Atom qt_net_wm_action_max_v;
+extern Atom qt_net_wm_action_fullscreen;
+extern Atom qt_net_wm_action_change_desktop;
+extern Atom qt_net_wm_action_close;
+extern Atom qt_net_wm_action_above;
+extern Atom qt_net_wm_action_below;
extern Atom qt_net_wm_window_type;
extern Atom qt_net_wm_window_type_normal;
extern Atom qt_net_wm_window_type_dialog;
@@ -462,7 +475,16 @@ void QWidget::create( WId window, bool initializeWindow, bool destroyOldWindow)
// NET window states
long net_winstates[6] = { 0, 0, 0, 0, 0, 0 };
+ long net_winactions[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int curr_winstate = 0;
+ int curr_winaction = 0;
+
+ // Add all default actions that cannot be turned off
+ net_winactions[curr_winaction++] = qt_net_wm_action_stick;
+ net_winactions[curr_winaction++] = qt_net_wm_action_fullscreen;
+ net_winactions[curr_winaction++] = qt_net_wm_action_change_desktop;
+ net_winactions[curr_winaction++] = qt_net_wm_action_above;
+ net_winactions[curr_winaction++] = qt_net_wm_action_below;
struct {
ulong flags, functions, decorations;
@@ -475,6 +497,56 @@ void QWidget::create( WId window, bool initializeWindow, bool destroyOldWindow)
mwmhints.input_mode = 0L;
mwmhints.status = 0L;
+ if ( testNFlags(WX11DisableResize) ) {
+ mwmhints.functions |= (1L << 1); // MWM_FUNC_RESIZE
+ mwmhints.functions |= (1L << 0); // MWM_FUNC_ALL
+ mwmhints.flags |= (1L << 0); // MWM_HINTS_FUNCTIONS
+ }
+ else {
+ net_winactions[curr_winaction++] = qt_net_wm_action_resize;
+ }
+
+ if ( testNFlags(WX11DisableMove) ) {
+ mwmhints.functions |= (1L << 2); // MWM_FUNC_MOVE
+ mwmhints.functions |= (1L << 0); // MWM_FUNC_ALL
+ mwmhints.flags |= (1L << 0); // MWM_HINTS_FUNCTIONS
+ }
+ else {
+ net_winactions[curr_winaction++] = qt_net_wm_action_move;
+ }
+
+ if ( testNFlags(WX11DisableMinimize) ) {
+ mwmhints.functions |= (1L << 3); // MWM_FUNC_MINIMIZE
+ mwmhints.functions |= (1L << 0); // MWM_FUNC_ALL
+ mwmhints.flags |= (1L << 0); // MWM_HINTS_FUNCTIONS
+ }
+ else {
+ net_winactions[curr_winaction++] = qt_net_wm_action_minimize;
+ }
+
+ if ( testNFlags(WX11DisableMaximize) ) {
+ mwmhints.functions |= (1L << 4); // MWM_FUNC_MAXIMIZE
+ mwmhints.functions |= (1L << 0); // MWM_FUNC_ALL
+ mwmhints.flags |= (1L << 0); // MWM_HINTS_FUNCTIONS
+ }
+ else {
+ net_winactions[curr_winaction++] = qt_net_wm_action_max_h;
+ net_winactions[curr_winaction++] = qt_net_wm_action_max_v;
+ }
+
+ if ( testNFlags(WX11DisableClose) ) {
+ mwmhints.functions |= (1L << 5); // MWM_FUNC_CLOSE
+ mwmhints.functions |= (1L << 0); // MWM_FUNC_ALL
+ mwmhints.flags |= (1L << 0); // MWM_HINTS_FUNCTIONS
+ }
+ else {
+ net_winactions[curr_winaction++] = qt_net_wm_action_close;
+ }
+
+ if ( ! testNFlags(WX11DisableShade) ) {
+ net_winactions[curr_winaction++] = qt_net_wm_action_shade;
+ }
+
if (topLevel && ! (desktop || popup)) {
ulong wsa_mask = 0;
@@ -630,6 +702,13 @@ void QWidget::create( WId window, bool initializeWindow, bool destroyOldWindow)
else
XDeleteProperty(dpy, id, qt_net_wm_state);
+ // set _NET_WM_ALLOWED_ACTIONS
+ if (curr_winaction > 0)
+ XChangeProperty(dpy, id, qt_net_wm_action, XA_ATOM, 32, PropModeReplace,
+ (unsigned char *) net_winactions, curr_winaction);
+ else
+ XDeleteProperty(dpy, id, qt_net_wm_action);
+
// set _NET_WM_PID
long curr_pid = getpid();
XChangeProperty(dpy, id, qt_net_wm_pid, XA_CARDINAL, 32, PropModeReplace,