Add Qt::WindowTransparentForMouseEvents

Add a flag for output only windows that are
transparent for mouse events and implement it
for the xcb backend.

Change-Id: I24afdb6b27de34bcdf0c061a5a4987ac2880e4ae
Reviewed-on: http://codereview.qt-project.org/5260
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
This commit is contained in:
Lars Knoll 2011-09-20 18:09:08 +02:00 committed by Qt by Nokia
parent e915b7924f
commit 0d4918950e
3 changed files with 43 additions and 0 deletions

View File

@ -258,6 +258,7 @@ public:
WindowContextHelpButtonHint = 0x00010000,
WindowShadeButtonHint = 0x00020000,
WindowStaysOnTopHint = 0x00040000,
WindowTransparentForInput = 0x00080000,
CustomizeWindowHint = 0x02000000,
WindowStaysOnBottomHint = 0x04000000,

View File

@ -57,6 +57,7 @@
#define class class_name
#include <xcb/xcb_icccm.h>
#undef class
#include <xcb/xfixes.h>
// xcb-icccm 3.8 support
#ifdef XCB_ICCCM_NUM_WM_SIZE_HINTS_ELEMENTS
@ -120,6 +121,7 @@ QXcbWindow::QXcbWindow(QWindow *window)
, m_window(0)
, m_syncCounter(0)
, m_mapped(false)
, m_transparent(false)
, m_netWmUserTimeWindow(XCB_NONE)
#if defined(XCB_USE_EGL)
, m_eglSurface(0)
@ -303,6 +305,9 @@ void QXcbWindow::create()
setWindowTitle(window()->windowTitle());
setWindowState(window()->windowState());
if (window()->windowFlags() & Qt::WindowTransparentForInput)
setTransparentForMouseEvents(true);
connection()->drag()->dndEnable(this, true);
}
@ -665,9 +670,16 @@ Qt::WindowFlags QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
if (type == Qt::Popup)
flags |= Qt::X11BypassWindowManagerHint;
if (flags & Qt::WindowTransparentForInput) {
uint32_t mask = XCB_EVENT_MASK_NO_EVENT;
xcb_change_window_attributes(xcb_connection(), xcb_window(), XCB_CW_EVENT_MASK, &mask);
}
setNetWmWindowFlags(flags);
setMotifWindowFlags(flags);
setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput);
return flags;
}
@ -974,6 +986,33 @@ void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp)
XCB_ATOM_CARDINAL, 32, 1, &timestamp);
}
void QXcbWindow::setTransparentForMouseEvents(bool transparent)
{
if (transparent == m_transparent)
return;
xcb_rectangle_t rectangle;
xcb_rectangle_t *rect = 0;
int nrect = 0;
if (!transparent) {
rectangle.x = 0;
rectangle.y = 0;
rectangle.width = geometry().width();
rectangle.height = geometry().height();
rect = &rectangle;
nrect = 1;
}
xcb_xfixes_region_t region = xcb_generate_id(xcb_connection());
xcb_xfixes_create_region(xcb_connection(), region, nrect, rect);
xcb_xfixes_set_window_shape_region_checked(xcb_connection(), m_window, XCB_SHAPE_SK_INPUT, 0, 0, region);
xcb_xfixes_destroy_region(xcb_connection(), region);
m_transparent = transparent;
}
WId QXcbWindow::winId() const
{

View File

@ -124,6 +124,8 @@ private:
void updateMotifWmHintsBeforeMap();
void updateNetWmStateBeforeMap();
void setTransparentForMouseEvents(bool transparent);
void create();
void destroy();
@ -143,6 +145,7 @@ private:
Qt::WindowState m_windowState;
bool m_mapped;
bool m_transparent;
xcb_window_t m_netWmUserTimeWindow;
QSurfaceFormat m_requestedFormat;