summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbwindow.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp238
1 files changed, 115 insertions, 123 deletions
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 429ba8df71..82ef8cc4df 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -196,6 +202,20 @@ static inline QImage::Format imageFormatForVisual(int depth, quint32 red_mask, q
case 16:
if (blue_mask == 0x1f)
return QImage::Format_RGB16;
+ if (red_mask == 0x1f) {
+ if (rgbSwap)
+ *rgbSwap = true;
+ return QImage::Format_RGB16;
+ }
+ break;
+ case 15:
+ if (blue_mask == 0x1f)
+ return QImage::Format_RGB555;
+ if (red_mask == 0x1f) {
+ if (rgbSwap)
+ *rgbSwap = true;
+ return QImage::Format_RGB555;
+ }
break;
default:
break;
@@ -266,7 +286,7 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s)
// TODO move this into a utility function in QWindow or QGuiApplication
static QWindow *childWindowAt(QWindow *win, const QPoint &p)
{
- foreach (QObject *obj, win->children()) {
+ for (QObject *obj : win->children()) {
if (obj->isWindowType()) {
QWindow *childWin = static_cast<QWindow *>(obj);
if (childWin->isVisible()) {
@@ -353,7 +373,7 @@ void QXcbWindow::create()
if (visual)
m_visualId = connection()->defaultVisualId();
if (!visual)
- qWarning() << "Could not use default visual id. Falling back to root_visual for screen.";
+ qWarning("Could not use default visual id. Falling back to root_visual for screen.");
}
if (!visual)
visual = platformScreen->visualForId(m_visualId);
@@ -362,18 +382,6 @@ void QXcbWindow::create()
return;
}
- const quint32 mask = XCB_CW_BACK_PIXMAP | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK;
- const quint32 values[] = {
- // XCB_CW_BACK_PIXMAP
- XCB_NONE,
- // XCB_CW_OVERRIDE_REDIRECT
- type == Qt::Popup || type == Qt::ToolTip || (window()->flags() & Qt::BypassWindowManagerHint),
- // XCB_CW_SAVE_UNDER
- type == Qt::Popup || type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip || type == Qt::Drawer,
- // XCB_CW_EVENT_MASK
- defaultEventMask
- };
-
// Parameters to XCreateWindow() are frame corner + inner size.
// This fits in case position policy is frame inclusive. There is
// currently no way to implement it for frame-exclusive geometries.
@@ -404,108 +412,76 @@ void QXcbWindow::create()
}
}
- resolveFormat();
-
-#ifdef XCB_USE_XLIB
- if (window()->surfaceType() != QSurface::RasterSurface
- && QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
- XVisualInfo *visualInfo = Q_NULLPTR;
- if (connection()->hasDefaultVisualId())
- visualInfo = CREATE_VISUALINFO_FROM_DEFAULT_VISUALID(this);
- if (!visualInfo)
- visualInfo = static_cast<XVisualInfo *>(createVisual());
-
- if (!visualInfo && window()->surfaceType() == QSurface::OpenGLSurface)
- qFatal("Could not initialize OpenGL");
-
- if (!visualInfo && window()->surfaceType() == QSurface::RasterGLSurface) {
- qWarning("Could not initialize OpenGL for RasterGLSurface, reverting to RasterSurface.");
- window()->setSurfaceType(QSurface::RasterSurface);
- }
-
- if (visualInfo) {
- m_depth = visualInfo->depth;
- m_imageFormat = imageFormatForVisual(visualInfo->depth, visualInfo->red_mask, visualInfo->blue_mask, &m_imageRgbSwap);
- Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), xcb_parent_id, visualInfo->visual, AllocNone);
+ resolveFormat(platformScreen->surfaceFormatFor(window()->requestedFormat()));
- XSetWindowAttributes a;
- a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(this), platformScreen->screenNumber());
- a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(this), platformScreen->screenNumber());
- a.colormap = cmap;
+ const xcb_visualtype_t *visual = Q_NULLPTR;
- m_visualId = visualInfo->visualid;
+ if (connection()->hasDefaultVisualId()) {
+ visual = platformScreen->visualForId(connection()->defaultVisualId());
+ if (!visual)
+ qWarning() << "Failed to use requested visual id.";
+ }
- m_window = XCreateWindow(DISPLAY_FROM_XCB(this), xcb_parent_id, rect.x(), rect.y(), rect.width(), rect.height(),
- 0, visualInfo->depth, InputOutput, visualInfo->visual,
- CWBackPixel|CWBorderPixel|CWColormap, &a);
+ if (!visual)
+ visual = createVisual();
- XFree(visualInfo);
- }
+ if (!visual) {
+ qWarning() << "Falling back to using screens root_visual.";
+ visual = platformScreen->visualForId(platformScreen->screen()->root_visual);
}
-#endif
- if (!m_window)
- {
- m_window = xcb_generate_id(xcb_connection());
- m_visualId = UINT_MAX;
- const xcb_visualtype_t *visual = Q_NULLPTR;
- m_depth = platformScreen->screen()->root_depth;
+ Q_ASSERT(visual);
- uint32_t mask = 0;
- uint32_t values[3];
+ m_visualId = visual->visual_id;
+ m_depth = platformScreen->depthOfVisual(m_visualId);
+ m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap);
+ xcb_colormap_t colormap = 0;
- if (connection()->hasDefaultVisualId()) {
- m_visualId = connection()->defaultVisualId();
- visual = platformScreen->visualForId(m_visualId);
- }
+ quint32 mask = XCB_CW_BACK_PIXMAP
+ | XCB_CW_BORDER_PIXEL
+ | XCB_CW_BIT_GRAVITY
+ | XCB_CW_OVERRIDE_REDIRECT
+ | XCB_CW_SAVE_UNDER
+ | XCB_CW_EVENT_MASK;
- if (!visual) {
- if (connection()->hasDefaultVisualId())
- qWarning("Failed to use default visual id. Falling back to using screens root_visual");
-
- m_visualId = platformScreen->screen()->root_visual;
-
- if (m_format.alphaBufferSize() == 8) {
- xcb_depth_iterator_t depthIter = xcb_screen_allowed_depths_iterator(platformScreen->screen());
- while (depthIter.rem) {
- if (depthIter.data->depth == 32) {
- xcb_visualtype_iterator_t visualIter = xcb_depth_visuals_iterator(depthIter.data);
- if (visualIter.rem) {
- m_visualId = visualIter.data->visual_id;
- m_depth = 32;
- uint32_t colormap = xcb_generate_id(xcb_connection());
- xcb_create_colormap(xcb_connection(), XCB_COLORMAP_ALLOC_NONE, colormap,
- xcb_parent_id, m_visualId);
- mask |= XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP;
- values[0] = platformScreen->screen()->white_pixel;
- values[1] = platformScreen->screen()->black_pixel;
- values[2] = colormap;
- break;
- }
- }
- xcb_depth_next(&depthIter);
- }
- }
+ static const bool haveOpenGL = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL);
- visual = platformScreen->visualForId(m_visualId);
- }
+ if ((window()->supportsOpenGL() && haveOpenGL) || m_format.hasAlpha()) {
+ colormap = xcb_generate_id(xcb_connection());
+ Q_XCB_CALL(xcb_create_colormap(xcb_connection(),
+ XCB_COLORMAP_ALLOC_NONE,
+ colormap,
+ xcb_parent_id,
+ m_visualId));
- m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap);
- Q_XCB_CALL(xcb_create_window(xcb_connection(),
- m_depth,
- m_window, // window id
- xcb_parent_id, // parent window id
- rect.x(),
- rect.y(),
- rect.width(),
- rect.height(),
- 0, // border width
- XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
- m_visualId, // visual
- mask,
- values));
+ mask |= XCB_CW_COLORMAP;
}
+ quint32 values[] = {
+ XCB_BACK_PIXMAP_NONE,
+ platformScreen->screen()->black_pixel,
+ XCB_GRAVITY_NORTH_WEST,
+ type == Qt::Popup || type == Qt::ToolTip || (window()->flags() & Qt::BypassWindowManagerHint),
+ type == Qt::Popup || type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip || type == Qt::Drawer,
+ defaultEventMask,
+ colormap
+ };
+
+ m_window = xcb_generate_id(xcb_connection());
+ Q_XCB_CALL(xcb_create_window(xcb_connection(),
+ m_depth,
+ m_window, // window id
+ xcb_parent_id, // parent window id
+ rect.x(),
+ rect.y(),
+ rect.width(),
+ rect.height(),
+ 0, // border width
+ XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
+ m_visualId, // visual
+ mask,
+ values));
+
connection()->addWindowEventListener(m_window, this);
Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
@@ -666,7 +642,7 @@ void QXcbWindow::setGeometry(const QRect &rect)
const QRect wmGeometry = windowToWmGeometry(rect);
- if (newScreen && newScreen != currentScreen)
+ if (newScreen != currentScreen)
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
if (qt_window_private(window())->positionAutomatic) {
@@ -902,7 +878,8 @@ void QXcbWindow::hide()
// Find the top level window at cursor position.
// Don't use QGuiApplication::topLevelAt(): search only the virtual siblings of this window's screen
QWindow *enterWindow = Q_NULLPTR;
- foreach (QPlatformScreen *screen, xcbScreen()->virtualSiblings()) {
+ const auto screens = xcbScreen()->virtualSiblings();
+ for (QPlatformScreen *screen : screens) {
if (screen->geometry().contains(cursorPos)) {
const QPoint devicePosition = QHighDpi::toNativePixels(cursorPos, screen->screen());
enterWindow = screen->topLevelAt(devicePosition);
@@ -1174,6 +1151,7 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
}
setWmWindowType(wmWindowTypes, flags);
+ setNetWmStateWindowFlags(flags);
setMotifWindowFlags(flags);
setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput);
@@ -1409,6 +1387,15 @@ void QXcbWindow::updateNetWmStateBeforeMap()
setNetWmStates(states);
}
+void QXcbWindow::setNetWmStateWindowFlags(Qt::WindowFlags flags)
+{
+ changeNetWmState(flags & Qt::WindowStaysOnTopHint,
+ atom(QXcbAtom::_NET_WM_STATE_ABOVE),
+ atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP));
+ changeNetWmState(flags & Qt::WindowStaysOnBottomHint,
+ atom(QXcbAtom::_NET_WM_STATE_BELOW));
+}
+
void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp)
{
xcb_window_t wid = m_window;
@@ -1677,7 +1664,7 @@ void QXcbWindow::requestActivateWindow()
return;
}
- if (!m_mapped || !xcbScreen()) {
+ if (!m_mapped) {
m_deferredActivation = true;
return;
}
@@ -2177,9 +2164,7 @@ void QXcbWindow::handleMapNotifyEvent(const xcb_map_notify_event_t *event)
if (m_deferredActivation)
requestActivateWindow();
- QRegion exposeRegion = QRect(QPoint(), geometry().size());
- compressExposeEvent(exposeRegion);
- QWindowSystemInterface::handleExposeEvent(window(), exposeRegion);
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
}
}
@@ -2577,6 +2562,12 @@ void QXcbWindow::updateSyncRequestCounter()
}
}
+const xcb_visualtype_t *QXcbWindow::createVisual()
+{
+ return xcbScreen() ? xcbScreen()->visualForFormat(m_format)
+ : nullptr;
+}
+
bool QXcbWindow::setKeyboardGrabEnabled(bool grab)
{
if (grab && !connection()->canGrab())
@@ -2848,3 +2839,4 @@ QXcbScreen *QXcbWindow::xcbScreen() const
}
QT_END_NAMESPACE
+