Make sure window state is synced back to Qt from the XCB plugin.
authorSamuel Rødal <samuel.rodal@nokia.com>
Fri, 7 Oct 2011 18:22:46 +0000 (20:22 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 7 Oct 2011 20:27:13 +0000 (22:27 +0200)
We should properly react to the property notify events.

Task-number: QTBUG-21856
Change-Id: I0d2aa90b7d8da3b96acf4d88684b0200de7d7413
Reviewed-on: http://codereview.qt-project.org/6266
Sanity-Review: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
src/plugins/platforms/xcb/qxcbconnection.cpp
src/plugins/platforms/xcb/qxcbwindow.cpp
src/plugins/platforms/xcb/qxcbwindow.h

index 3d1a145..08c569c 100644 (file)
@@ -527,9 +527,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
         handled = false;
         break;
     case XCB_PROPERTY_NOTIFY:
-        setTime(((xcb_property_notify_event_t *)event)->time);
-//        qDebug() << "XCB_PROPERTY_NOTIFY";
-        handled = false;
+        HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
         break;
     default:
         handled = false;
index 48a59ec..4d2e5b0 100644 (file)
@@ -1331,6 +1331,53 @@ void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
     QWindowSystemInterface::handleLeaveEvent(window());
 }
 
+void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *event)
+{
+    connection()->setTime(event->time);
+
+    bool propertyDeleted = event->state == XCB_PROPERTY_DELETE;
+
+    if (event->atom == atom(QXcbAtom::_NET_WM_STATE) || event->atom == atom(QXcbAtom::WM_STATE)) {
+        if (propertyDeleted)
+            return;
+
+        xcb_get_property_cookie_t get_cookie =
+            xcb_get_property(xcb_connection(), 0, m_window, atom(QXcbAtom::WM_STATE),
+                             XCB_ATOM_ANY, 0, 1024);
+
+        xcb_generic_error_t *error;
+
+        xcb_get_property_reply_t *reply =
+            xcb_get_property_reply(xcb_connection(), get_cookie, &error);
+
+        xcb_atom_t wm_state = XCB_WM_STATE_WITHDRAWN;
+        if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) {
+            if (reply->length != 0)
+                wm_state = ((long *)xcb_get_property_value(reply))[0];
+            free(reply);
+        } else if (error) {
+            connection()->handleXcbError(error);
+            free(error);
+        }
+
+        QVector<xcb_atom_t> netWmState = getNetWmState();
+
+        bool maximized = netWmState.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ))
+            && netWmState.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT));
+        bool fullscreen = netWmState.contains(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN));
+
+        Qt::WindowState state = Qt::WindowNoState;
+        if (wm_state == XCB_WM_STATE_ICONIC)
+            state = Qt::WindowMinimized;
+        else if (maximized)
+            state = Qt::WindowMaximized;
+        else if (fullscreen)
+            state = Qt::WindowFullScreen;
+
+        QWindowSystemInterface::handleWindowStateChanged(window(), state);
+    }
+}
+
 void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *)
 {
     QWindowSystemInterface::handleWindowActivated(window());
index f470bbc..f33ff5c 100644 (file)
@@ -103,6 +103,7 @@ public:
     void handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event);
     void handleFocusInEvent(const xcb_focus_in_event_t *event);
     void handleFocusOutEvent(const xcb_focus_out_event_t *event);
+    void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event);
 
     void handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers);