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. QWaylandCompositor question

QWaylandCompositor question

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 2 Posters 389 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.
  • S Offline
    S Offline
    SQEW
    wrote on last edited by SQEW
    #1

    Hi,

    I'm trying to convert the Pure QML Wayland compositor example into C++.

    main.cpp

    #include "compositor.h"
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts,true);
        QGuiApplication app(argc,argv);
        Compositor *compositor=new Compositor;
        return app.exec();
    }
    

    compositor.h

    #ifndef COMPOSITOR_H
    #define COMPOSITOR_H
    #include <QWaylandCompositor>
    #include <QWaylandOutput>
    #include <QWaylandXdgShell>
    #include <QQuickView>
    #include "chrome.h"
    class Compositor:public QWaylandCompositor
    {
        Q_OBJECT
    
    public:
        Compositor();
    
    private:
        QWaylandOutput *m_output=nullptr;
        QWaylandXdgShell *m_xdgShell=nullptr;
    
    private slots:
        void createdChangedSlot();
        void toplevelCreatedSlot(QWaylandXdgToplevel *toplevel,QWaylandXdgSurface *xdgSurface);
    };
    #endif
    

    compositor.cpp

    #include "compositor.h"
    Compositor::Compositor()
    {    
        setSocketName("testcomp");
        setUseHardwareIntegrationExtension(true);
        connect(this,SIGNAL(createdChanged()),this,SLOT(createdChangedSlot()));
        m_xdgShell=new QWaylandXdgShell(this);
     connect(m_xdgShell,SIGNAL(toplevelCreated(QWaylandXdgToplevel*,QWaylandXdgSurface*)),SLOT(toplevelCreatedSlot(QWaylandXdgToplevel*,QWaylandXdgSurface*)));
    
        Chrome::rootWindow=new QQuickView(QUrl("qrc:/testcomp/Root.qml"));
        create();
    }
    
    void Compositor::createdChangedSlot()
    {
        if(isCreated()){
            m_output=new QWaylandOutput(this,Chrome::rootWindow);
            m_output->setSizeFollowsWindow(true);
        }
    }
    
    void Compositor::toplevelCreatedSlot(QWaylandXdgToplevel *toplevel,QWaylandXdgSurface *surface)
    {
        Chrome::list.append(new Chrome(toplevel,surface));
    }
    

    chrome.h

    #ifndef CHROME_H
    #define CHROME_H
    
    #include <QWaylandQuickShellSurfaceItem>
    #include <QWaylandXdgToplevel>
    
    class Chrome:public QWaylandQuickShellSurfaceItem
    {
        Q_OBJECT
    
    public:
        explicit Chrome(QWaylandXdgToplevel *toplevel,QWaylandShellSurface *surface);
        ~Chrome();
        static QList<Chrome*> list;
        static QQuickView *rootWindow;
    
    private:
        QWaylandXdgToplevel *m_toplevel;
    };
    #endif
    

    chrome.cpp

    #include "chrome.h"
    Chrome::Chrome(QWaylandXdgToplevel *toplevel,QWaylandShellSurface *surface)
    {
        m_toplevel=toplevel;
        setParentItem(rootWindow->contentItem());
        setShellSurface(surface);
    }
    QList<Chrome*> Chrome::list;
    QQuickView *Chrome::rootWindow;
    

    Root.qml

    import QtQuick
    Rectangle{
        anchors.fill:parent
        color:'black'
    }
    

    Running this code gets me a semi-working compositor, which allows me to open other Qt-based apps in it (by setting WAYLAND_DISPLAY=testcomp). I can maximize/unmaximize them and close them using the titlebar buttons, but the apps themselves do not respond to any mouse clicks. (Interestingly, right-button clicks appear to work, and popup menus appear). Apps with animated content (like projectM-pulseaudio) show up but do not 'animate', while they work fine in the QML example.

    I run the compositor nested in another (for now).

    I am guessing I need to do something with the QWaylandXdgTopLevel object, but I don't know what, and I can't figure it out from the QML example either.

    I would really appreciate it if somebody could help me out.

    S 1 Reply Last reply
    0
    • S SQEW

      Hi,

      I'm trying to convert the Pure QML Wayland compositor example into C++.

      main.cpp

      #include "compositor.h"
      int main(int argc, char *argv[])
      {
          QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts,true);
          QGuiApplication app(argc,argv);
          Compositor *compositor=new Compositor;
          return app.exec();
      }
      

      compositor.h

      #ifndef COMPOSITOR_H
      #define COMPOSITOR_H
      #include <QWaylandCompositor>
      #include <QWaylandOutput>
      #include <QWaylandXdgShell>
      #include <QQuickView>
      #include "chrome.h"
      class Compositor:public QWaylandCompositor
      {
          Q_OBJECT
      
      public:
          Compositor();
      
      private:
          QWaylandOutput *m_output=nullptr;
          QWaylandXdgShell *m_xdgShell=nullptr;
      
      private slots:
          void createdChangedSlot();
          void toplevelCreatedSlot(QWaylandXdgToplevel *toplevel,QWaylandXdgSurface *xdgSurface);
      };
      #endif
      

      compositor.cpp

      #include "compositor.h"
      Compositor::Compositor()
      {    
          setSocketName("testcomp");
          setUseHardwareIntegrationExtension(true);
          connect(this,SIGNAL(createdChanged()),this,SLOT(createdChangedSlot()));
          m_xdgShell=new QWaylandXdgShell(this);
       connect(m_xdgShell,SIGNAL(toplevelCreated(QWaylandXdgToplevel*,QWaylandXdgSurface*)),SLOT(toplevelCreatedSlot(QWaylandXdgToplevel*,QWaylandXdgSurface*)));
      
          Chrome::rootWindow=new QQuickView(QUrl("qrc:/testcomp/Root.qml"));
          create();
      }
      
      void Compositor::createdChangedSlot()
      {
          if(isCreated()){
              m_output=new QWaylandOutput(this,Chrome::rootWindow);
              m_output->setSizeFollowsWindow(true);
          }
      }
      
      void Compositor::toplevelCreatedSlot(QWaylandXdgToplevel *toplevel,QWaylandXdgSurface *surface)
      {
          Chrome::list.append(new Chrome(toplevel,surface));
      }
      

      chrome.h

      #ifndef CHROME_H
      #define CHROME_H
      
      #include <QWaylandQuickShellSurfaceItem>
      #include <QWaylandXdgToplevel>
      
      class Chrome:public QWaylandQuickShellSurfaceItem
      {
          Q_OBJECT
      
      public:
          explicit Chrome(QWaylandXdgToplevel *toplevel,QWaylandShellSurface *surface);
          ~Chrome();
          static QList<Chrome*> list;
          static QQuickView *rootWindow;
      
      private:
          QWaylandXdgToplevel *m_toplevel;
      };
      #endif
      

      chrome.cpp

      #include "chrome.h"
      Chrome::Chrome(QWaylandXdgToplevel *toplevel,QWaylandShellSurface *surface)
      {
          m_toplevel=toplevel;
          setParentItem(rootWindow->contentItem());
          setShellSurface(surface);
      }
      QList<Chrome*> Chrome::list;
      QQuickView *Chrome::rootWindow;
      

      Root.qml

      import QtQuick
      Rectangle{
          anchors.fill:parent
          color:'black'
      }
      

      Running this code gets me a semi-working compositor, which allows me to open other Qt-based apps in it (by setting WAYLAND_DISPLAY=testcomp). I can maximize/unmaximize them and close them using the titlebar buttons, but the apps themselves do not respond to any mouse clicks. (Interestingly, right-button clicks appear to work, and popup menus appear). Apps with animated content (like projectM-pulseaudio) show up but do not 'animate', while they work fine in the QML example.

      I run the compositor nested in another (for now).

      I am guessing I need to do something with the QWaylandXdgTopLevel object, but I don't know what, and I can't figure it out from the QML example either.

      I would really appreciate it if somebody could help me out.

      S Offline
      S Offline
      SQEW
      wrote on last edited by SQEW
      #2

      I condensed the QML example down to the following:

      import QtQuick
      import QtWayland.Compositor
      import QtWayland.Compositor.XdgShell
      Item{
          WaylandCompositor{
              id:waylandCompositor
              WaylandOutput{
                  id:output
                  compositor:waylandCompositor
                  property ListModel shellSurfaces:ListModel{}
                  function handleShellSurface(shellSurface){shellSurfaces.append({shellSurface:shellSurface});}
                  sizeFollowsWindow:true
                  window:Window{
                      width:1024
                      height:760
                      visible:true
                      Repeater{
                          model:output.shellSurfaces
                          ShellSurfaceItem{
                              shellSurface:modelData
                              onSurfaceDestroyed:output.shellSurfaces.remove(index)
                          }
                      }
                  }
              }
              XdgShell{
                  onToplevelCreated:{
                      console.log(xdgSurface)
      
                      output.handleShellSurface(xdgSurface)
                  }
              }
          }
      }
      

      I really wish the Qt devs didn't obscure the inner working of the compositor behind their QML like this. It looks very simple on the surface but the use of the Repeater here does things that I am unable to replicate in C++.

      So what is the proper way to display a QWaylandXdgSurface on a QWaylandOutput?

      Could somebody please help? I've been stuck on this for days and I am unable to make any meaningful progress. The documentation is hugely confusing as well.

      1 Reply Last reply
      0
      • S Offline
        S Offline
        SQEW
        wrote on last edited by
        #3
        This post is deleted!
        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi,

          This module is likely part of the set that are less used by people on this forum. You might want to check on the interest mailing list. You'll find there Qt's developers/maintainers.

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

          S 1 Reply Last reply
          0
          • SGaistS SGaist

            Hi,

            This module is likely part of the set that are less used by people on this forum. You might want to check on the interest mailing list. You'll find there Qt's developers/maintainers.

            S Offline
            S Offline
            SQEW
            wrote on last edited by
            #5

            @SGaist

            Hi,

            Thanks, I'll check it out.

            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