From 3b69fa6bc70efe6f14cb67546812f611b891709c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 9 Mar 2012 11:38:55 +0100 Subject: Implement QSystemTrayIcon for X11. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reimplement using a QWidget. Use X Change-Id: I7f8326598fb7210d59bc1d682cdada4526d5b6dd Reviewed-by: Samuel Rødal --- src/widgets/util/qsystemtrayicon_p.h | 56 ----- src/widgets/util/qsystemtrayicon_x11.cpp | 367 +++++++++++++------------------ src/widgets/util/util.pri | 3 + 3 files changed, 153 insertions(+), 273 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/util/qsystemtrayicon_p.h b/src/widgets/util/qsystemtrayicon_p.h index cf7d794696..f7344df19c 100644 --- a/src/widgets/util/qsystemtrayicon_p.h +++ b/src/widgets/util/qsystemtrayicon_p.h @@ -122,62 +122,6 @@ private: int timerId; }; -#if defined(Q_WS_X11) -QT_BEGIN_INCLUDE_NAMESPACE -#include -#include -#include -#include -QT_END_INCLUDE_NAMESPACE - -class QSystemTrayIconSys : public QWidget -{ - friend class QSystemTrayIconPrivate; - -public: - QSystemTrayIconSys(QSystemTrayIcon *q); - ~QSystemTrayIconSys(); - enum { - SYSTEM_TRAY_REQUEST_DOCK = 0, - SYSTEM_TRAY_BEGIN_MESSAGE = 1, - SYSTEM_TRAY_CANCEL_MESSAGE =2 - }; - - void addToTray(); - void updateIcon(); - XVisualInfo* getSysTrayVisualInfo(); - - // QObject::event is public but QWidget's ::event() re-implementation - // is protected ;( - inline bool deliverToolTipEvent(QEvent *e) - { return QWidget::event(e); } - - static Window sysTrayWindow; - static QList trayIcons; - static QCoreApplication::EventFilter oldEventFilter; - static bool sysTrayTracker(void *message, long *result); - static Window locateSystemTray(); - static Atom sysTraySelection; - static XVisualInfo sysTrayVisual; - -protected: - void paintEvent(QPaintEvent *pe); - void resizeEvent(QResizeEvent *re); - bool x11Event(XEvent *event); - void mousePressEvent(QMouseEvent *event); - void mouseDoubleClickEvent(QMouseEvent *event); -#ifndef QT_NO_WHEELEVENT - void wheelEvent(QWheelEvent *event); -#endif - bool event(QEvent *e); - -private: - QPixmap background; - QSystemTrayIcon *q; - Colormap colormap; -}; -#endif // Q_WS_X11 - QT_END_NAMESPACE #endif // QT_NO_SYSTEMTRAYICON diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp index c5071b339d..174c39d1f6 100644 --- a/src/widgets/util/qsystemtrayicon_x11.cpp +++ b/src/widgets/util/qsystemtrayicon_x11.cpp @@ -39,9 +39,7 @@ ** ****************************************************************************/ -#include "private/qt_x11_p.h" #include "qlabel.h" -#include "qx11info_x11.h" #include "qpainter.h" #include "qpixmap.h" #include "qbitmap.h" @@ -52,236 +50,165 @@ #include "qtimer.h" #include "qsystemtrayicon_p.h" #include "qpaintengine.h" +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include #ifndef QT_NO_SYSTEMTRAYICON QT_BEGIN_NAMESPACE -Window QSystemTrayIconSys::sysTrayWindow = XNone; -QList QSystemTrayIconSys::trayIcons; -QCoreApplication::EventFilter QSystemTrayIconSys::oldEventFilter = 0; -Atom QSystemTrayIconSys::sysTraySelection = XNone; -XVisualInfo QSystemTrayIconSys::sysTrayVisual = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +enum { + SYSTEM_TRAY_REQUEST_DOCK = 0, + SYSTEM_TRAY_BEGIN_MESSAGE = 1, + SYSTEM_TRAY_CANCEL_MESSAGE =2 +}; -// Locate the system tray -Window QSystemTrayIconSys::locateSystemTray() +// ### fixme (15.3.2012): The following issues need to be resolved: +// - Tracking of the actual tray window for DestroyNotify and re-creation +// of the icons on the new window should it change (see Qt 4.X). + +// Global context for the X11 system tray containing a display for the primary +// screen and a selection atom from which the tray window can be determined. +class QX11SystemTrayContext { - Display *display = QX11Info::display(); - if (sysTraySelection == XNone) { - int screen = QX11Info::appScreen(); - QString net_sys_tray = QString::fromLatin1("_NET_SYSTEM_TRAY_S%1").arg(screen); - sysTraySelection = XInternAtom(display, net_sys_tray.toLatin1(), False); - } +public: + QX11SystemTrayContext(); + ~QX11SystemTrayContext(); - return XGetSelectionOwner(QX11Info::display(), sysTraySelection); -} + bool isValid() const { return m_systemTraySelection != 0; } -XVisualInfo* QSystemTrayIconSys::getSysTrayVisualInfo() -{ - Display *display = QX11Info::display(); - - if (!sysTrayVisual.visual) { - Window win = locateSystemTray(); - if (win != XNone) { - Atom actual_type; - int actual_format; - ulong nitems, bytes_remaining; - uchar *data = 0; - int result = XGetWindowProperty(display, win, ATOM(_NET_SYSTEM_TRAY_VISUAL), 0, 1, - False, XA_VISUALID, &actual_type, - &actual_format, &nitems, &bytes_remaining, &data); - VisualID vid = 0; - if (result == Success && data && actual_type == XA_VISUALID && actual_format == 32 && - nitems == 1 && bytes_remaining == 0) - vid = *(VisualID*)data; - if (data) - XFree(data); - if (vid == 0) - return 0; - - uint mask = VisualIDMask; - XVisualInfo *vi, rvi; - int count; - rvi.visualid = vid; - vi = XGetVisualInfo(display, mask, &rvi, &count); - if (vi) { - sysTrayVisual = vi[0]; - XFree((char*)vi); - } - if (sysTrayVisual.depth != 32) - memset(&sysTrayVisual, 0, sizeof(sysTrayVisual)); - } - } + inline Display *display() const { return m_display; } + inline int screenNumber() const { return m_screenNumber; } + Window locateSystemTray() const; - return sysTrayVisual.visual ? &sysTrayVisual : 0; -} +private: + Display *m_display; + int m_screenNumber; + Atom m_systemTraySelection; +}; -bool QSystemTrayIconSys::sysTrayTracker(void *message, long *result) +QX11SystemTrayContext::QX11SystemTrayContext() : m_display(0), m_screenNumber(0), m_systemTraySelection(0) { - bool retval = false; - if (QSystemTrayIconSys::oldEventFilter) - retval = QSystemTrayIconSys::oldEventFilter(message, result); - - if (trayIcons.isEmpty()) - return retval; - - Display *display = QX11Info::display(); - XEvent *ev = (XEvent *)message; - if (ev->type == DestroyNotify && ev->xany.window == sysTrayWindow) { - sysTrayWindow = locateSystemTray(); - memset(&sysTrayVisual, 0, sizeof(sysTrayVisual)); - for (int i = 0; i < trayIcons.count(); i++) { - if (sysTrayWindow == XNone) { - QBalloonTip::hideBalloon(); - trayIcons[i]->hide(); // still no luck - trayIcons[i]->destroy(); - trayIcons[i]->create(); - } else - trayIcons[i]->addToTray(); // add it to the new tray - } - retval = true; - } else if (ev->type == ClientMessage && sysTrayWindow == XNone) { - static Atom manager_atom = XInternAtom(display, "MANAGER", False); - XClientMessageEvent *cm = (XClientMessageEvent *)message; - if ((cm->message_type == manager_atom) && ((Atom)cm->data.l[1] == sysTraySelection)) { - sysTrayWindow = cm->data.l[2]; - memset(&sysTrayVisual, 0, sizeof(sysTrayVisual)); - XSelectInput(display, sysTrayWindow, StructureNotifyMask); - for (int i = 0; i < trayIcons.count(); i++) { - trayIcons[i]->addToTray(); - } - retval = true; - } - } else if (ev->type == PropertyNotify && ev->xproperty.atom == ATOM(_NET_SYSTEM_TRAY_VISUAL) && - ev->xproperty.window == sysTrayWindow) { - memset(&sysTrayVisual, 0, sizeof(sysTrayVisual)); - for (int i = 0; i < trayIcons.count(); i++) { - trayIcons[i]->addToTray(); - } + QScreen *screen = QGuiApplication::primaryScreen(); + if (!screen) { + qWarning("%s: No screen.", Q_FUNC_INFO); + return; + } + // Open display using screen name and retrieve screen number from "hostname:0.0" + const QByteArray name = screen->name().toLocal8Bit(); + const int dotPos = name.lastIndexOf('.'); + if (dotPos != -1) { + bool ok; + const int n = name.mid(dotPos + 1).toInt(&ok); + if (ok) + m_screenNumber = n; + } + m_display = XOpenDisplay(name.constData()); + if (!m_display) { + qWarning("%s: Cannot open display '%s'.", Q_FUNC_INFO, name.constData()); + return; } - return retval; + const QByteArray netSysTray = "_NET_SYSTEM_TRAY_S" + QByteArray::number(m_screenNumber); + m_systemTraySelection = XInternAtom(m_display, netSysTray.constData(), False); + if (!m_systemTraySelection) { + qWarning("%s: Unable to retrieve atom '%s'.", Q_FUNC_INFO, netSysTray.constData()); + return; + } } -QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *q) - : QWidget(0, Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint), - q(q), colormap(0) +Window QX11SystemTrayContext::locateSystemTray() const { - setAttribute(Qt::WA_AlwaysShowToolTips); - setAttribute(Qt::WA_QuitOnClose, false); - setAttribute(Qt::WA_NoSystemBackground, true); - setAttribute(Qt::WA_PaintOnScreen); - - static bool eventFilterAdded = false; - Display *display = QX11Info::display(); - if (!eventFilterAdded) { - oldEventFilter = qApp->setEventFilter(sysTrayTracker); - eventFilterAdded = true; - Window root = QX11Info::appRootWindow(); - XWindowAttributes attr; - XGetWindowAttributes(display, root, &attr); - if ((attr.your_event_mask & StructureNotifyMask) != StructureNotifyMask) { - (void) QApplication::desktop(); // lame trick to ensure our event mask is not overridden - XSelectInput(display, root, attr.your_event_mask | StructureNotifyMask); // for MANAGER selection - } - } - if (trayIcons.isEmpty()) { - sysTrayWindow = locateSystemTray(); - if (sysTrayWindow != XNone) - XSelectInput(display, sysTrayWindow, StructureNotifyMask); // track tray events - } - trayIcons.append(this); - setMouseTracking(true); -#ifndef QT_NO_TOOLTIP - setToolTip(q->toolTip()); -#endif - if (sysTrayWindow != XNone) - addToTray(); + if (isValid()) + return XGetSelectionOwner(m_display, m_systemTraySelection); + return 0; } -QSystemTrayIconSys::~QSystemTrayIconSys() +QX11SystemTrayContext::~QX11SystemTrayContext() { - trayIcons.removeAt(trayIcons.indexOf(this)); - Display *display = QX11Info::display(); - if (trayIcons.isEmpty()) { - if (sysTrayWindow == XNone) - return; - if (display) - XSelectInput(display, sysTrayWindow, 0); // stop tracking the tray - sysTrayWindow = XNone; - } - if (colormap) - XFreeColormap(display, colormap); + if (m_display) + XCloseDisplay(m_display); } -void QSystemTrayIconSys::addToTray() +Q_GLOBAL_STATIC(QX11SystemTrayContext, qX11SystemTrayContext) + +// System tray widget. Could be replaced by a QWindow with +// a backing store if it did not need tooltip handling. +class QSystemTrayIconSys : public QWidget { - Q_ASSERT(sysTrayWindow != XNone); - Display *display = QX11Info::display(); - - XVisualInfo *vi = getSysTrayVisualInfo(); - if (vi && vi->visual) { - Window root = RootWindow(display, vi->screen); - Window p = root; - if (QWidget *pw = parentWidget()) - p = pw->effectiveWinId(); - colormap = XCreateColormap(display, root, vi->visual, AllocNone); - XSetWindowAttributes wsa; - wsa.background_pixmap = 0; - wsa.colormap = colormap; - wsa.background_pixel = 0; - wsa.border_pixel = 0; - Window wid = XCreateWindow(display, p, -1, -1, 1, 1, - 0, vi->depth, InputOutput, vi->visual, - CWBackPixmap|CWBackPixel|CWBorderPixel|CWColormap, &wsa); - create(wid); - } else { - XSetWindowBackgroundPixmap(display, winId(), ParentRelative); - } +public: + explicit QSystemTrayIconSys(QSystemTrayIcon *q); + + inline void updateIcon() { update(); } + inline QSystemTrayIcon *systemTrayIcon() const { return q; } + + QRect globalGeometry() const; + +protected: + virtual void mousePressEvent(QMouseEvent *ev); + virtual void mouseDoubleClickEvent(QMouseEvent *ev); + virtual bool event(QEvent *); + virtual void paintEvent(QPaintEvent *); - // GNOME, NET WM Specification +private: + QSystemTrayIcon *q; +}; + +QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn) : + q(qIn) +{ + setToolTip(q->toolTip()); + QX11SystemTrayContext *context = qX11SystemTrayContext(); + Q_ASSERT(context->isValid()); + setAttribute(Qt::WA_AlwaysShowToolTips, true); + setAttribute(Qt::WA_TranslucentBackground, true); + setAttribute(Qt::WA_QuitOnClose, false); + setWindowFlags(Qt::Window | Qt::FramelessWindowHint); + const QSize size(22, 22); // Gnome, standard size + setGeometry(QRect(QPoint(0, 0), size)); + setMinimumSize(size); + createWinId(); + setMouseTracking(true); + + Display *display = context->display(); + + // Request to be a tray window according to GNOME, NET WM Specification static Atom netwm_tray_atom = XInternAtom(display, "_NET_SYSTEM_TRAY_OPCODE", False); long l[5] = { CurrentTime, SYSTEM_TRAY_REQUEST_DOCK, winId(), 0, 0 }; XEvent ev; memset(&ev, 0, sizeof(ev)); ev.xclient.type = ClientMessage; - ev.xclient.window = sysTrayWindow; + ev.xclient.window = context->locateSystemTray(); ev.xclient.message_type = netwm_tray_atom; ev.xclient.format = 32; memcpy((char *)&ev.xclient.data, (const char *) l, sizeof(l)); - XSendEvent(display, sysTrayWindow, False, 0, &ev); - setMinimumSize(22, 22); // required at least on GNOME -} - -void QSystemTrayIconSys::updateIcon() -{ - update(); + XSendEvent(display, ev.xclient.window, False, 0, &ev); + XSync(display, False); + show(); } -void QSystemTrayIconSys::resizeEvent(QResizeEvent *re) +QRect QSystemTrayIconSys::globalGeometry() const { - QWidget::resizeEvent(re); - updateIcon(); + QX11SystemTrayContext *context = qX11SystemTrayContext(); + ::Window dummy; + int x, y, rootX, rootY; + unsigned int width, height, border, depth; + // Use X11 API since we are parented on the tray, about which the QWindow does not know. + XGetGeometry(context->display(), winId(), &dummy, &x, &y, &width, &height, &border, &depth); + XTranslateCoordinates(context->display(), winId(), + XRootWindow(context->display(), context->screenNumber()), + x, y, &rootX, &rootY, &dummy); + return QRect(QPoint(rootX, rootY), QSize(width, height)); } -void QSystemTrayIconSys::paintEvent(QPaintEvent*) -{ - QPainter p(this); - if (!getSysTrayVisualInfo()) { - const QRegion oldSystemClip = p.paintEngine()->systemClip(); - const QRect clearedRect = oldSystemClip.boundingRect(); - XClearArea(QX11Info::display(), winId(), clearedRect.x(), clearedRect.y(), - clearedRect.width(), clearedRect.height(), False); - QPaintEngine *pe = p.paintEngine(); - pe->setSystemClip(clearedRect); - q->icon().paint(&p, rect()); - pe->setSystemClip(oldSystemClip); - } else { - p.setCompositionMode(QPainter::CompositionMode_Source); - p.fillRect(rect(), Qt::transparent); - p.setCompositionMode(QPainter::CompositionMode_SourceOver); - q->icon().paint(&p, rect()); - } -} void QSystemTrayIconSys::mousePressEvent(QMouseEvent *ev) { @@ -308,41 +235,45 @@ void QSystemTrayIconSys::mouseDoubleClickEvent(QMouseEvent *ev) emit q->activated(QSystemTrayIcon::DoubleClick); } -#ifndef QT_NO_WHEELEVENT -void QSystemTrayIconSys::wheelEvent(QWheelEvent *e) -{ - QApplication::sendEvent(q, e); -} -#endif - bool QSystemTrayIconSys::event(QEvent *e) { - if (e->type() == QEvent::ToolTip) { + switch (e->type()) { +#ifndef QT_NO_WHEELEVENT + case QEvent::Wheel: return QApplication::sendEvent(q, e); +#endif + default: + break; } return QWidget::event(e); } -bool QSystemTrayIconSys::x11Event(XEvent *event) +void QSystemTrayIconSys::paintEvent(QPaintEvent *) { - if (event->type == ReparentNotify) - show(); - return QWidget::x11Event(event); + // Note: Transparent pixels require a particular Visual which XCB + // currently does not support yet. + const QRect rect(QPoint(0, 0), geometry().size()); + QPainter painter(this); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.fillRect(rect, Qt::transparent); + painter.setCompositionMode(QPainter::CompositionMode_SourceOver); + q->icon().paint(&painter, rect); } //////////////////////////////////////////////////////////////////////////// + void QSystemTrayIconPrivate::install_sys() { Q_Q(QSystemTrayIcon); - if (!sys) + if (!sys && qX11SystemTrayContext()->isValid()) sys = new QSystemTrayIconSys(q); } QRect QSystemTrayIconPrivate::geometry_sys() const { if (!sys) - return QRect(); - return QRect(sys->mapToGlobal(QPoint(0, 0)), sys->size()); + return QRect(); + return sys->globalGeometry(); } void QSystemTrayIconPrivate::remove_sys() @@ -357,9 +288,8 @@ void QSystemTrayIconPrivate::remove_sys() void QSystemTrayIconPrivate::updateIcon_sys() { - if (!sys) - return; - sys->updateIcon(); + if (sys) + sys->updateIcon(); } void QSystemTrayIconPrivate::updateMenu_sys() @@ -378,7 +308,10 @@ void QSystemTrayIconPrivate::updateToolTip_sys() bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys() { - return QSystemTrayIconSys::locateSystemTray() != XNone; + const QString platform = QGuiApplication::platformName(); + if (platform.compare(QStringLiteral("xcb"), Qt::CaseInsensitive) == 0) + return qX11SystemTrayContext()->locateSystemTray() != None; + return false; } bool QSystemTrayIconPrivate::supportsMessages_sys() @@ -391,8 +324,8 @@ void QSystemTrayIconPrivate::showMessage_sys(const QString &message, const QStri { if (!sys) return; - QPoint g = sys->mapToGlobal(QPoint(0, 0)); - QBalloonTip::showBalloon(icon, message, title, sys->q, + const QPoint g = sys->globalGeometry().topLeft(); + QBalloonTip::showBalloon(icon, message, title, sys->systemTrayIcon(), QPoint(g.x() + sys->width()/2, g.y() + sys->height()/2), msecs); } diff --git a/src/widgets/util/util.pri b/src/widgets/util/util.pri index 16765558f6..958958f469 100644 --- a/src/widgets/util/util.pri +++ b/src/widgets/util/util.pri @@ -29,6 +29,9 @@ SOURCES += \ win32:!wince* { SOURCES += util/qsystemtrayicon_win.cpp +} else:contains(QT_CONFIG, xcb) { + SOURCES += util/qsystemtrayicon_x11.cpp + CONFIG += x11 } else { SOURCES += util/qsystemtrayicon_qpa.cpp } -- cgit v1.2.3 From b895dfd641e512dfbeb9b9a141614f5b5d12dbd0 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 23 Mar 2012 11:34:17 +0100 Subject: Fix warnings in qtbase. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I981e08872440e35eb9bfad32b20543cfce8439c9 Reviewed-by: Samuel Rødal --- src/widgets/itemviews/qdirmodel.cpp | 1 - src/widgets/kernel/qwidget.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'src/widgets') diff --git a/src/widgets/itemviews/qdirmodel.cpp b/src/widgets/itemviews/qdirmodel.cpp index 490c272e39..6ecf3c75aa 100644 --- a/src/widgets/itemviews/qdirmodel.cpp +++ b/src/widgets/itemviews/qdirmodel.cpp @@ -1162,7 +1162,6 @@ QFileInfo QDirModel::fileInfo(const QModelIndex &index) const void QDirModelPrivate::init() { - Q_Q(QDirModel); filters = QDir::AllEntries | QDir::NoDotAndDotDot; sort = QDir::Name; nameFilters << QLatin1String("*"); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 63eb2540ff..9a32d952f9 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -8441,6 +8441,7 @@ void QWidget::mouseReleaseEvent(QMouseEvent *event) void QWidget::mouseDoubleClickEvent(QMouseEvent *event) { + Q_UNUSED(event) } #ifndef QT_NO_WHEELEVENT -- cgit v1.2.3 From f195a8e2b69eba0e3c44f2dece222b0da9e06026 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 13 Feb 2012 14:05:51 +0100 Subject: Added QAccessibleGroupBox MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added a new accessible interface for QGroupBox, as QAccessibleDisplay is not good enough when the QGroupBox is checkable. AccessibleFactory was modified to return a QAccessibleGroupBox when the accessible interface of a QGroupBox is requested. Created tst_QAccessibility::groupBoxTest Port to Qt5 of the patch by José Millán Soto Change-Id: I6c23dcf5562b3ea269b04102e78463b65827188a Reviewed-by: Jan-Arve Sæther (cherry picked from commit c03ceb203c65d9e3485fad848bfc0c4b6ee3e9aa) --- src/widgets/widgets/qgroupbox.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/widgets') diff --git a/src/widgets/widgets/qgroupbox.cpp b/src/widgets/widgets/qgroupbox.cpp index e9edea286f..d8ad04cd84 100644 --- a/src/widgets/widgets/qgroupbox.cpp +++ b/src/widgets/widgets/qgroupbox.cpp @@ -643,6 +643,12 @@ void QGroupBox::setChecked(bool b) update(); d->checked = b; d->_q_setChildrenEnabled(b); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::State st; + st.checked = true; + QAccessibleStateChangeEvent *ev = new QAccessibleStateChangeEvent(this, st); + QAccessible::updateAccessibility(ev); +#endif emit toggled(b); } } -- cgit v1.2.3 From cea1a6bcd51a43bad6426e4de81fda117f094932 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Tue, 13 Mar 2012 20:25:12 +0100 Subject: Make sure windows send accessibility activated updates. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both QWindow and QWidgetWindow should update with the active state signal. Change-Id: I0219f803aa0fb109765f0faa0aedb120c2a439f0 Reviewed-by: Jan-Arve Sæther --- src/widgets/accessible/qaccessiblewidget.cpp | 2 ++ src/widgets/kernel/qwidgetwindow_qpa.cpp | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index 790b51102c..ae050ac643 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -557,6 +557,8 @@ QAccessible::State QAccessibleWidget::state() const state.movable = true; if (w->minimumSize() != w->maximumSize()) state.sizeable = true; + if (w->isActiveWindow()) + state.active = true; } return state; diff --git a/src/widgets/kernel/qwidgetwindow_qpa.cpp b/src/widgets/kernel/qwidgetwindow_qpa.cpp index 7a13e2032e..ed7371a9bd 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa.cpp +++ b/src/widgets/kernel/qwidgetwindow_qpa.cpp @@ -96,8 +96,14 @@ bool QWidgetWindow::event(QEvent *event) // these should not be sent to QWidget, the corresponding events // are sent by QApplicationPrivate::notifyActiveWindowChange() case QEvent::FocusIn: - case QEvent::FocusOut: - return false; + case QEvent::FocusOut: { +#ifndef QT_NO_ACCESSIBILITY + QAccessible::State state; + state.active = true; + QAccessibleStateChangeEvent ev(widget(), state); + QAccessible::updateAccessibility(&ev); +#endif + return false; } case QEvent::FocusAboutToChange: if (QApplicationPrivate::focus_widget) { -- cgit v1.2.3 From b2363a935c8dac2c332c79d4c10c99be89656047 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 22 Mar 2012 17:43:25 +0100 Subject: Fix QGuiApplication::keyboardModifiers() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure that the keybaord modifiers are maintained properly when handling window system events. Change-Id: Ie75cbe5eb509c29e3d2291694f2de509fbf3098a Reviewed-by: Morten Johan Sørvig Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qapplication.cpp | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index ce57e2868d..2615ac891d 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -3014,34 +3014,14 @@ bool QApplication::notify(QObject *receiver, QEvent *e) // capture the current mouse/keyboard state if(e->spontaneous()) { - if (e->type() == QEvent::KeyPress - || e->type() == QEvent::KeyRelease) { - QKeyEvent *ke = static_cast(e); - QApplicationPrivate::modifier_buttons = ke->modifiers(); - } else if(e->type() == QEvent::MouseButtonPress + if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease) { QMouseEvent *me = static_cast(e); - QApplicationPrivate::modifier_buttons = me->modifiers(); if(me->type() == QEvent::MouseButtonPress) QApplicationPrivate::mouse_buttons |= me->button(); else QApplicationPrivate::mouse_buttons &= ~me->button(); } -#if !defined(QT_NO_WHEELEVENT) || !defined(QT_NO_TABLETEVENT) - else if (false -# ifndef QT_NO_WHEELEVENT - || e->type() == QEvent::Wheel -# endif -# ifndef QT_NO_TABLETEVENT - || e->type() == QEvent::TabletMove - || e->type() == QEvent::TabletPress - || e->type() == QEvent::TabletRelease -# endif - ) { - QInputEvent *ie = static_cast(e); - QApplicationPrivate::modifier_buttons = ie->modifiers(); - } -#endif // !QT_NO_WHEELEVENT || !QT_NO_TABLETEVENT } #ifndef QT_NO_GESTURES -- cgit v1.2.3 From bc0b37d6b61fc8ab83026d6a5e515666e58d7938 Mon Sep 17 00:00:00 2001 From: Pekka Vuorela Date: Fri, 16 Mar 2012 14:08:13 +0200 Subject: Password editor mask delay stylable by platform plugin Replaced hard coding as QT_GUI_PASSWORD_ECHO_DELAY with a style hint. Change-Id: I0b78ebad723dbe19d9b9496583203e31545874e2 Reviewed-by: Andrew den Exter Reviewed-by: Lars Knoll --- src/widgets/widgets/qwidgetlinecontrol.cpp | 26 ++++---------------------- src/widgets/widgets/qwidgetlinecontrol_p.h | 8 -------- 2 files changed, 4 insertions(+), 30 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp index ca30c7eef8..b4a7007190 100644 --- a/src/widgets/widgets/qwidgetlinecontrol.cpp +++ b/src/widgets/widgets/qwidgetlinecontrol.cpp @@ -47,6 +47,7 @@ #include "qclipboard.h" #include #include +#include #ifndef QT_NO_ACCESSIBILITY #include "qaccessible.h" #endif @@ -58,21 +59,6 @@ QT_BEGIN_NAMESPACE -#ifdef QT_GUI_PASSWORD_ECHO_DELAY -static const int qt_passwordEchoDelay = QT_GUI_PASSWORD_ECHO_DELAY; -#endif - -/*! - \macro QT_GUI_PASSWORD_ECHO_DELAY - - \internal - - Defines the amount of time in milliseconds the last entered character - should be displayed unmasked in the Password echo mode. - - If not defined in qplatformdefs.h there will be no delay in masking - password characters. -*/ /*! \internal @@ -113,7 +99,6 @@ void QWidgetLineControl::updateDisplayText(bool forceUpdate) if (m_echoMode == QLineEdit::Password) { str.fill(m_passwordCharacter); -#ifdef QT_GUI_PASSWORD_ECHO_DELAY if (m_passwordEchoTimer != 0 && m_cursor > 0 && m_cursor <= m_text.length()) { int cursor = m_cursor - 1; QChar uc = m_text.at(cursor); @@ -126,7 +111,6 @@ void QWidgetLineControl::updateDisplayText(bool forceUpdate) str[cursor - 1] = uc; } } -#endif } else if (m_echoMode == QLineEdit::PasswordEchoOnEdit && !m_passwordEchoEditing) { str.fill(m_passwordCharacter); } @@ -818,13 +802,13 @@ void QWidgetLineControl::addCommand(const Command &cmd) */ void QWidgetLineControl::internalInsert(const QString &s) { -#ifdef QT_GUI_PASSWORD_ECHO_DELAY if (m_echoMode == QLineEdit::Password) { if (m_passwordEchoTimer != 0) killTimer(m_passwordEchoTimer); - m_passwordEchoTimer = startTimer(qt_passwordEchoDelay); + int delay = qGuiApp->styleHints()->passwordMaskDelay(); + if (delay > 0) + m_passwordEchoTimer = startTimer(delay); } -#endif if (hasSelectedText()) addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend)); if (m_maskData) { @@ -1517,12 +1501,10 @@ void QWidgetLineControl::timerEvent(QTimerEvent *event) } else if (event->timerId() == m_tripleClickTimer) { killTimer(m_tripleClickTimer); m_tripleClickTimer = 0; -#ifdef QT_GUI_PASSWORD_ECHO_DELAY } else if (event->timerId() == m_passwordEchoTimer) { killTimer(m_passwordEchoTimer); m_passwordEchoTimer = 0; updateDisplayText(); -#endif } } diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h index 72f25e9068..62184a27bb 100644 --- a/src/widgets/widgets/qwidgetlinecontrol_p.h +++ b/src/widgets/widgets/qwidgetlinecontrol_p.h @@ -93,9 +93,7 @@ public: m_ascent(0), m_maxLength(32767), m_lastCursorPos(-1), m_tripleClickTimer(0), m_maskData(0), m_modifiedState(0), m_undoState(0), m_selstart(0), m_selend(0), m_passwordEchoEditing(false) -#ifdef QT_GUI_PASSWORD_ECHO_DELAY , m_passwordEchoTimer(0) -#endif #if defined(Q_WS_MAC) , m_threadChecks(false) , m_textLayoutThread(0) @@ -306,10 +304,8 @@ public: void updatePasswordEchoEditing(bool editing); bool passwordEchoEditing() const { -#ifdef QT_GUI_PASSWORD_ECHO_DELAY if (m_passwordEchoTimer != 0) return true; -#endif return m_passwordEchoEditing ; } @@ -484,17 +480,13 @@ private: bool m_passwordEchoEditing; QChar m_passwordCharacter; -#ifdef QT_GUI_PASSWORD_ECHO_DELAY int m_passwordEchoTimer; -#endif void cancelPasswordEchoTimer() { -#ifdef QT_GUI_PASSWORD_ECHO_DELAY if (m_passwordEchoTimer != 0) { killTimer(m_passwordEchoTimer); m_passwordEchoTimer = 0; } -#endif } int redoTextLayout() const; -- cgit v1.2.3