Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] Qt 4.8.5 Focus bug, keyPresses routed via menu, OSX only

[SOLVED] Qt 4.8.5 Focus bug, keyPresses routed via menu, OSX only

Scheduled Pinned Locked Moved General and Desktop
12 Posts 2 Posters 4.7k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #2

    Hi,

    Can you create a minimal compile example of this ?

    Interested in AI ? www.idiap.ch
    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

    1 Reply Last reply
    0
    • S Offline
      S Offline
      sipickles
      wrote on last edited by
      #3

      Here's a minimal example:

      TestWidget.h
      @#ifndef TESTWIDGET_H
      #define TESTWIDGET_H

      #include <QtGui/QtGui>
      #include <QtCore/QObject>

      class TestWidget: public QWidget
      {
      Q_OBJECT
      public:
      TestWidget();

      public Q_SLOTS:
      void onPressP1();
      void onPressP2();

      private:
      QStackedWidget* _stack;
      };

      #endif // TESTWIDGET_H
      @

      TestWidget.cpp
      @#include "testpanel.h"

      #include <QtGui/QtGui>
      #include <QtOpenGL/QGLWidget>

      TestWidget::TestWidget() : QWidget()
      {
      QVBoxLayout* layout = new QVBoxLayout();
      setLayout(layout);
      _stack = new QStackedWidget();
      QPushButton* b1 = new QPushButton("p1");
      QPushButton* b2 = new QPushButton("p2");

      layout->addWidget(b1);
      layout->addWidget(b2);
      layout->addWidget(_stack);

      //QLabel* page1 = new QLabel("PAGE 1");
      QGLWidget* page1 = new QGLWidget();
      _stack->addWidget(page1);

      QTextEdit* page2 = new QTextEdit();
      _stack->addWidget(page2);

      connect(b1, SIGNAL(pressed()), this, SLOT(onPressP1()));
      connect(b2, SIGNAL(pressed()), this, SLOT(onPressP2()));
      }

      void TestWidget::onPressP1()
      {
      qDebug() << "onPressP1";
      _stack->setCurrentIndex(0);
      }
      void TestWidget::onPressP2()
      {
      qDebug() << "onPressP2";
      _stack->setCurrentIndex(1);
      setFocusProxy(_stack->currentWidget());
      }
      @

      main.cpp
      @#include <QtCore/QCoreApplication>
      #include <QtGui/QtGui>

      #include "testpanel.h"

      int main(int argc, char *argv[])
      {
      QApplication app(argc, argv);

      QMainWindow* mw = new QMainWindow();
      mw->show();

      TestWidget* t = new TestWidget();
      t->setParent(mw);
      t->show();

      return app.exec();
      }@

      I dont have a .pro file - not using qmake projects, but its standard stuff.

      Once compiled, expand the window. There are 2 buttons and an uncleared QGLWidget. If you switch between the two pages of the QStackedWidget, you suddenly cannot type in the QTextEdit any more.

      If you recompile with a QLabel for page1 instead of a QGLWidget, it works fine. In fact setting any widget to use the WA_NativeWindow flag also breaks it.

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #4

        I just tested it with on 10.8.5 and can confirm the behavior for Qt 4.8.5 but it works on Qt 5.2. Can you open a bug report "here":http://bugreports.qt-project.com ?

        Posting the link to it would be great

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • S Offline
          S Offline
          sipickles
          wrote on last edited by
          #5

          Thanks for testing... I'll log a bug

          1 Reply Last reply
          0
          • S Offline
            S Offline
            sipickles
            wrote on last edited by
            #6

            https://bugreports.qt-project.org/browse/QTBUG-34371

            1 Reply Last reply
            0
            • S Offline
              S Offline
              sipickles
              wrote on last edited by
              #7

              I really need a patch or workaround for this. Can anyone help?

              1 Reply Last reply
              0
              • S Offline
                S Offline
                sipickles
                wrote on last edited by
                #8

                I've reported the bug, but it looks like no suggestion will be forthcoming any time soon. So I am trying to debug myself.

                More info. I've tried different combinations of widgets in the QStackedWidget:

                Working
                page1: QQLWidget
                page2: QLabel, QPushButton, QWidget or QGLWidget

                Working
                page1: QLineEdit, QPlainTextEdit or QTextEdit
                page2: QLineEdit, QPlainTextEdit or QTextEdit

                Broken
                page1: QGLWidget
                page2: QLineEdit, QPlainTextEdit, QTextEdit or QComboBox

                Broken
                page1: QLineEdit, QPlainTextEdit, QTextEdit or QComboBox
                page2: QGLWidget

                So to reproduce it you definitely need a QGLWidget and some sort of widget which accepts focus in the same stack.

                Significantly, you can switch between the two pages and see key presses received correctly (using an event filter). It works until you focus the focusable widget (the QTextEdit becomes the QApplication::focusWidget()). Then when you change pages and back, it is broken.

                EDIT - Found that QComboBox also exhibits the problem, so its not confined to text entry widgets

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  sipickles
                  wrote on last edited by
                  #9

                  My debug efforts show that in the scenario where a QStackedWidget has a mix of Native and alien widgets in its stack, the focussing is broken. Exact repro steps:

                  • start app which has a QStackedWidget showing page1. Page1 is a widget with WA_NativeWindow set. Page2 is a Widget which accepts focus, eg QLineEdit.
                  • switch to page2. Focus the widget with the mouse. You can type in the QLineEdit .
                  • switch to page1. QStackedLayout::setCurrentIndex switches focus from the QLineEdit to the Native widget.
                  • switch to page2. QStackedLayout::setCurrentIndex tries to focus the QLineEdit, but this line returns NIL, qwidget_mac.mm:3914, QWidgetPrivate::setFocus_sys:

                  @NSView *view = qt_mac_nativeview_for(q);@

                  The next line then does makeFirstResponder:nil, which unfocuses widgets and routes further keyboard events to the top level application instead.

                  My patch ensures we always get a valid native view by calling:

                  @NSView *view = qt_mac_effectiveview_for(q);@

                  Is this the right approach?

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    sipickles
                    wrote on last edited by
                    #10

                    Further evidence that my fix is correct. It brings OSX into line with other platforms. On windows, we setFocus on the effectiveWinId. But on OSX, we were using internalWinID.

                    On Windows, qwidget_win.cpp:

                    @void QWidgetPrivate::setFocus_sys()
                    {
                    Q_Q(QWidget);
                    if (q->testAttribute(Qt::WA_WState_Created) && q->window()->windowType() != Qt::Popup)
                    SetFocus(q->effectiveWinId());
                    }@

                    On OSX, qwidget_mac.mm:
                    @void QWidgetPrivate::setFocus_sys()
                    {
                    Q_Q(QWidget);
                    if (q->testAttribute(Qt::WA_WState_Created)) {
                    #ifdef QT_MAC_USE_COCOA
                    QMacCocoaAutoReleasePool pool;
                    //NSView *view = qt_mac_nativeview_for(q); // WRONG as it uses internalWinId
                    NSView *view = qt_mac_effectiveview_for(q); // CORRECT as it uses effectiveWinId
                    [[view window] makeFirstResponder:view];
                    #else
                    SetKeyboardFocus(qt_mac_window_for(q), qt_mac_nativeview_for(q), 1);
                    #endif
                    }
                    }

                    Q_GUI_EXPORT OSViewRef qt_mac_nativeview_for(const QWidget *w)
                    {
                    return reinterpret_cast<OSViewRef>(w->internalWinId());
                    }

                    Q_GUI_EXPORT OSViewRef qt_mac_effectiveview_for(const QWidget *w)
                    {
                    // Get the first non-alien (parent) widget for
                    // w, and return its NSView (if it has one):
                    return reinterpret_cast<OSViewRef>(w->effectiveWinId());
                    }
                    @

                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      sipickles
                      wrote on last edited by
                      #11

                      Thanks for submitting the patch, SGaist!

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #12

                        You're welcome !

                        Since it will be working now, please update the thread title prepending [solved] so other forum users may know a solution has been found :)

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved