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. How to avoid bringing QMainWindow to the front when clicking on independent QWidget on MacOS
QtWS25 Last Chance

How to avoid bringing QMainWindow to the front when clicking on independent QWidget on MacOS

Scheduled Pinned Locked Moved Solved General and Desktop
mac osqwidgetqmainwindowactivateqt5
8 Posts 2 Posters 1.4k Views
  • 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.
  • R Offline
    R Offline
    RaulSanchez
    wrote on last edited by
    #1

    Hello all,
    I am building an Qt app on MacOS. The app is composed by QMainWindow and independent QWidget.
    I want the widget to be always on top so I have added these window flags:
    Qt::X11BypassWindowManagerHint;
    Qt::FramelessWindowHint;
    Qt::WindowStaysOnTopHint;
    Qt::CustomizeWindowHint;
    Qt::WindowDoesNotAcceptFocus;

    And also these attributes
    Qt::WA_ShowWithoutActivating
    Qt::WA_LayoutUsesWidgetRect
    Qt::WA_TranslucentBackground
    Qt::WA_OpaquePaintEvent
    Qt::WA_PaintUnclipped

    On MacOS and only on MacOS I am seeing that when I click on the widget the QMainWindow always comes to the front.
    I do not want that to happen. How can I achieve it?
    I have tried to intercept mouse click events but that does not seem to work. I have also tried to intercept QWindow activate event but also no success there.
    I need help here please. Is that desired behaviour on MacOS? Is it bug on MacOS?
    Thanks and regards

    1 Reply Last reply
    0
    • R Offline
      R Offline
      RaulSanchez
      wrote on last edited by
      #8

      I made it work by removing this flag: Qt::WindowDoesNotAcceptFocus

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

        Hi and welcome to devnet,

        Which version of Qt ?
        On which version of macOS ?
        Can you provide a minimal compilable example that shows that behaviour ?

        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
        • R Offline
          R Offline
          RaulSanchez
          wrote on last edited by
          #3

          MacoS version is 10.15.7 Catalina
          Regarding Qt versions I have tried using Qt5.9.7 and Qt 5.15. Both have same behaviour
          Here is minimal example:
          mainwindow.h

          #ifndef MAINWINDOW_H
          #define MAINWINDOW_H
          
          #include <QMainWindow>
          
          class MainWindow : public QMainWindow
          {
              Q_OBJECT
          public:
              MainWindow();
          protected:
              virtual bool eventFilter(QObject *o, QEvent *e) override;
          };
          #endif // MAINWINDOW_H
          

          mainwindow.cpp

          #include "mainwindow.h"
          
          #include <QDebug>
          #include <QEvent>
          
          MainWindow::MainWindow()
          {
              installEventFilter(this);
          }
          
          bool MainWindow::eventFilter(QObject *o, QEvent *e)
          {
              //qCritical() << "MainWindow::eventFilter --> " << e->type();
              if (e->type() == QEvent::WindowActivate) {
                  qCritical() << "QEvent::WindowActivate";
                  //e->setAccepted(false);
                  return true;
              }
              return QWidget::eventFilter(o, e);
          }
          

          widget.h

          #ifndef WIDGET_H
          #define WIDGET_H
          
          #include <QWidget>
          
          class Widget : public QWidget
          {
          public:
              explicit Widget(QWidget *parent = Q_NULLPTR);
          protected:
              virtual bool eventFilter(QObject *o, QEvent *e) override;
              virtual void mousePressEvent(QMouseEvent *event) override;
          };
          #endif // WIDGET_H
          

          widget.cpp

          #include "Widget.h"
          
          #include <QEvent>
          #include <QMouseEvent>
          #include <QDebug>
          
          namespace
          {
          Qt::WindowFlags defaultWindowFlags()
          {
              Qt::WindowFlags f = 0;
          
              f |= Qt::X11BypassWindowManagerHint;
              f |= Qt::FramelessWindowHint;
              f |= Qt::WindowStaysOnTopHint;
              f |= Qt::CustomizeWindowHint;
              f |= Qt::WindowDoesNotAcceptFocus;
          
          #if defined(Q_OS_WIN)
              f |= Qt::Tool;
          #else
              f |= Qt::Window;
          #endif // defined(Q_OS_WIN)
              return f;
          }
          }
          
          Widget::Widget(QWidget *parent) : QWidget(parent, defaultWindowFlags())
          {
              setFixedSize(100,100);
              setStyleSheet("background-color:blue;");
              move(56,89);
              setVisible(true);
              //installEventFilter(this);
              setAttribute(Qt::WA_TransparentForMouseEvents);
          }
          
          bool Widget::eventFilter(QObject *o, QEvent *e)
          {
              if (e->type() == QEvent::WindowActivate) {
                  qCritical() << "Widget QEvent::WindowActivate";
                  return true;
                  }
              if (e->type() == QEvent::MouseButtonPress) {
                  qCritical() << "Widget QEvent::MouseButtonPress";
                   //show();
                   //activateWindow();
                   //raise();
                   // false means it should be send to target also. as in , we dont remove it.
                   // if you return true , you will take the event and widget never sees it so be carefull with that.
                   return true;
               }
               return QWidget::eventFilter(o, e);
          }
          
          void Widget::mousePressEvent(QMouseEvent *event)
          {
             //event->accept();
             qCritical() << "mousePressEvent";
          }
          

          And finally main.cpp

          #include <QApplication>
          #include "mainwindow.h"
          #include "Widget.h"
          
          int main(int argc, char *argv[])
          {
              QApplication app(argc, argv);
              //MainWindow w;
              //w.show();
              RegularWindow r;
              r.show();
              Widget mywidget;
              return app.exec();
          }
          
          

          Just to add more info. I have seen that if I instantiate two main windows only it works as expected. Clicking on one of those mainwindows does not make the other mainwindow to get activated
          Thanks

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

            Hi,

            When you do nothing in methods of a subclass you should at least call the base class implementation.

            And when you call the base class implementation, you should ensure that you have right base class. In your code you call QWidget::eventFilter rather than QMainWindow.

            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
            1
            • R Offline
              R Offline
              RaulSanchez
              wrote on last edited by
              #5

              Hello @SGaist,
              Yes you're right, but I just created quick and basic example. I don't think these errors affect the goal of my question.
              Do you know how to get the behaviour I asked ?
              Thanks!

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

                That's the thing: they might.

                The goal of the minimum example is to remove all possible outside influences and concentrate on the issue at hand so having some methods re-implemented in a "quick and dirty" manner might in fact add or even be the issue.

                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
                1
                • R Offline
                  R Offline
                  RaulSanchez
                  wrote on last edited by
                  #7

                  Resubmitting example fixed:
                  main.cpp

                  #include <QApplication>
                  #include "mainwindow.h"
                  #include "Widget.h"
                  
                  int main(int argc, char *argv[])
                  {
                      QApplication app(argc, argv);
                      MainWindow w;
                      w.show();
                      Widget mywidget;
                      return app.exec();
                  }
                  

                  widget.h

                  #ifndef WIDGET_H
                  #define WIDGET_H
                  
                  #include <QWidget>
                  
                  class Widget : public QWidget
                  {
                  public:
                      explicit Widget(QWidget *parent = Q_NULLPTR);
                  };
                  #endif // WIDGET_H
                  

                  widget.cpp

                  #include "Widget.h"
                  
                  #include <QEvent>
                  #include <QMouseEvent>
                  #include <QDebug>
                  
                  namespace
                  {
                  Qt::WindowFlags defaultWindowFlags()
                  {
                      Qt::WindowFlags f = 0;
                  
                      f |= Qt::X11BypassWindowManagerHint;
                      f |= Qt::FramelessWindowHint;
                      f |= Qt::WindowStaysOnTopHint;
                      f |= Qt::CustomizeWindowHint;
                      f |= Qt::WindowDoesNotAcceptFocus;
                  
                  #if defined(Q_OS_WIN)
                      f |= Qt::Tool;
                  #else
                      f |= Qt::Window;
                  #endif // defined(Q_OS_WIN)
                      return f;
                  }
                  }
                  
                  Widget::Widget(QWidget *parent) : QWidget(parent, defaultWindowFlags())
                  {
                      setFixedSize(100,100);
                      setStyleSheet("background-color:blue;");
                      move(56,89);
                      setVisible(true);
                      setAttribute(Qt::WA_TransparentForMouseEvents);
                  }
                  

                  mainwindow.h

                  #ifndef MAINWINDOW_H
                  #define MAINWINDOW_H
                  
                  #include <QMainWindow>
                  
                  class MainWindow : public QMainWindow
                  {
                      Q_OBJECT
                  public:
                      MainWindow();
                  protected:
                      virtual bool eventFilter(QObject *o, QEvent *e) override;
                  };
                  #endif // MAINWINDOW_H
                  

                  mainwindow.cpp

                  #include "mainwindow.h"
                  
                  #include <QDebug>
                  #include <QEvent>
                  
                  MainWindow::MainWindow() : QMainWindow()
                  {
                      installEventFilter(this);
                  }
                  
                  bool MainWindow::eventFilter(QObject *o, QEvent *e)
                  {
                      //qCritical() << "MainWindow::eventFilter --> " << e->type();
                      if (e->type() == QEvent::WindowActivate) {
                          qCritical() << "QEvent::WindowActivate";
                          //e->setAccepted(false);
                          return true;
                      }
                      return QMainWindow::eventFilter(o, e);
                  }
                  

                  So, basically I have reduced example to be really simple. Still the behaviour is not correct. Could you help me on this?
                  Thanks in advance

                  1 Reply Last reply
                  0
                  • R Offline
                    R Offline
                    RaulSanchez
                    wrote on last edited by
                    #8

                    I made it work by removing this flag: Qt::WindowDoesNotAcceptFocus

                    1 Reply Last reply
                    1

                    • Login

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