summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-02-09 10:38:36 (GMT)
committerSamuel Rødal <samuel.rodal@nokia.com>2011-02-09 10:38:36 (GMT)
commita0cc1e923e1d43bbb86d59b829c2d8a23a03bcf4 (patch)
tree7e847ba2d3137fec847c35875773c7c745171d6b /src/plugins/platforms
parent6aa7b8ff77a968a2ad11181d21812e3fe675ba23 (diff)
downloadQt-a0cc1e923e1d43bbb86d59b829c2d8a23a03bcf4.zip
Qt-a0cc1e923e1d43bbb86d59b829c2d8a23a03bcf4.tar.gz
Qt-a0cc1e923e1d43bbb86d59b829c2d8a23a03bcf4.tar.bz2
Added window attribute setting to XCB backend.
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp154
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h1
2 files changed, 145 insertions, 10 deletions
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index caeb3fa..b54a233 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -90,9 +90,14 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
mask, // value mask
values); // value list
- xcb_atom_t properties[] = {
- atom(QXcbAtom::WM_DELETE_WINDOW)
- };
+ xcb_atom_t properties[4];
+ int propertyCount = 0;
+ properties[propertyCount++] = atom(QXcbAtom::WM_DELETE_WINDOW);
+ properties[propertyCount++] = atom(QXcbAtom::WM_TAKE_FOCUS);
+ properties[propertyCount++] = atom(QXcbAtom::_NET_WM_PING);
+
+ if (tlw->windowFlags() & Qt::WindowContextHelpButtonHint)
+ properties[propertyCount++] = atom(QXcbAtom::_NET_WM_CONTEXT_HELP);
xcb_change_property(xcb_connection(),
XCB_PROP_MODE_REPLACE,
@@ -100,7 +105,7 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
atom(QXcbAtom::WM_PROTOCOLS),
4,
32,
- sizeof(properties) / sizeof(xcb_atom_t),
+ propertyCount,
properties);
}
@@ -127,14 +132,144 @@ void QXcbWindow::setVisible(bool visible)
xcb_unmap_window(xcb_connection(), m_window);
}
+struct QtMWMHints {
+ quint32 flags, functions, decorations;
+ qint32 input_mode;
+ quint32 status;
+};
+
+enum {
+ MWM_HINTS_FUNCTIONS = (1L << 0),
+
+ MWM_FUNC_ALL = (1L << 0),
+ MWM_FUNC_RESIZE = (1L << 1),
+ MWM_FUNC_MOVE = (1L << 2),
+ MWM_FUNC_MINIMIZE = (1L << 3),
+ MWM_FUNC_MAXIMIZE = (1L << 4),
+ MWM_FUNC_CLOSE = (1L << 5),
+
+ MWM_HINTS_DECORATIONS = (1L << 1),
+
+ MWM_DECOR_ALL = (1L << 0),
+ MWM_DECOR_BORDER = (1L << 1),
+ MWM_DECOR_RESIZEH = (1L << 2),
+ MWM_DECOR_TITLE = (1L << 3),
+ MWM_DECOR_MENU = (1L << 4),
+ MWM_DECOR_MINIMIZE = (1L << 5),
+ MWM_DECOR_MAXIMIZE = (1L << 6),
+
+ MWM_HINTS_INPUT_MODE = (1L << 2),
+
+ MWM_INPUT_MODELESS = 0L,
+ MWM_INPUT_PRIMARY_APPLICATION_MODAL = 1L,
+ MWM_INPUT_FULL_APPLICATION_MODAL = 3L
+};
+
Qt::WindowFlags QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
{
- return flags;
-}
+ Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
+
+ if (type == Qt::ToolTip)
+ flags |= Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint;
+ if (type == Qt::Popup)
+ flags |= Qt::X11BypassWindowManagerHint;
+
+ bool topLevel = (flags & Qt::Window);
+ bool popup = (type == Qt::Popup);
+ bool dialog = (type == Qt::Dialog
+ || type == Qt::Sheet);
+ bool desktop = (type == Qt::Desktop);
+ bool tool = (type == Qt::Tool || type == Qt::SplashScreen
+ || type == Qt::ToolTip || type == Qt::Drawer);
+
+ Q_UNUSED(topLevel);
+ Q_UNUSED(dialog);
+ Q_UNUSED(desktop);
+ Q_UNUSED(tool);
+
+ bool tooltip = (type == Qt::ToolTip);
+
+ QtMWMHints mwmhints;
+ mwmhints.flags = 0L;
+ mwmhints.functions = 0L;
+ mwmhints.decorations = 0;
+ mwmhints.input_mode = 0L;
+ mwmhints.status = 0L;
+
+ if (type != Qt::SplashScreen) {
+ mwmhints.flags |= MWM_HINTS_DECORATIONS;
+
+ bool customize = flags & Qt::CustomizeWindowHint;
+ if (!(flags & Qt::FramelessWindowHint) && !(customize && !(flags & Qt::WindowTitleHint))) {
+ mwmhints.decorations |= MWM_DECOR_BORDER;
+ mwmhints.decorations |= MWM_DECOR_RESIZEH;
+
+ if (flags & Qt::WindowTitleHint)
+ mwmhints.decorations |= MWM_DECOR_TITLE;
+
+ if (flags & Qt::WindowSystemMenuHint)
+ mwmhints.decorations |= MWM_DECOR_MENU;
+
+ if (flags & Qt::WindowMinimizeButtonHint) {
+ mwmhints.decorations |= MWM_DECOR_MINIMIZE;
+ mwmhints.functions |= MWM_FUNC_MINIMIZE;
+ }
+
+ if (flags & Qt::WindowMaximizeButtonHint) {
+ mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
+ mwmhints.functions |= MWM_FUNC_MAXIMIZE;
+ }
+
+ if (flags & Qt::WindowCloseButtonHint)
+ mwmhints.functions |= MWM_FUNC_CLOSE;
+ }
+ } else {
+ // if type == Qt::SplashScreen
+ mwmhints.decorations = MWM_DECOR_ALL;
+ }
-Qt::WindowFlags QXcbWindow::windowFlags() const
-{
- return 0;
+ if (mwmhints.functions != 0) {
+ mwmhints.flags |= MWM_HINTS_FUNCTIONS;
+ mwmhints.functions |= MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
+ } else {
+ mwmhints.functions = MWM_FUNC_ALL;
+ }
+
+ if (!(flags & Qt::FramelessWindowHint)
+ && flags & Qt::CustomizeWindowHint
+ && flags & Qt::WindowTitleHint
+ && !(flags &
+ (Qt::WindowMinimizeButtonHint
+ | Qt::WindowMaximizeButtonHint
+ | Qt::WindowCloseButtonHint)))
+ {
+ // a special case - only the titlebar without any button
+ mwmhints.flags = MWM_HINTS_FUNCTIONS;
+ mwmhints.functions = MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
+ mwmhints.decorations = 0;
+ }
+
+ if (mwmhints.flags != 0l) {
+ xcb_change_property(xcb_connection(),
+ XCB_PROP_MODE_REPLACE,
+ m_window,
+ atom(QXcbAtom::_MOTIF_WM_HINTS),
+ atom(QXcbAtom::_MOTIF_WM_HINTS),
+ 32,
+ 5,
+ &mwmhints);
+ } else {
+ xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_MOTIF_WM_HINTS));
+ }
+
+ if (popup || tooltip) {
+ const quint32 mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER;
+ const quint32 values[] = { true, true };
+
+ xcb_change_window_attributes(xcb_connection(), m_window, mask, values);
+ }
+
+ return QPlatformWindow::setWindowFlags(flags);
}
WId QXcbWindow::winId() const
@@ -177,6 +312,7 @@ void QXcbWindow::lower()
void QXcbWindow::requestActivateWindow()
{
+ xcb_set_input_focus(xcb_connection(), m_window, XCB_INPUT_FOCUS_PARENT, XCB_TIME_CURRENT_TIME);
}
void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event)
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index d9ca86c..17e1742 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -60,7 +60,6 @@ public:
void setVisible(bool visible);
Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
- Qt::WindowFlags windowFlags() const;
WId winId() const;
void setParent(const QPlatformWindow *window);