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 notify style change to apps ?
Forum Updated to NodeBB v4.3 + New Features

How to notify style change to apps ?

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 2 Posters 1.4k 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.
  • D Offline
    D Offline
    dextermagnific
    wrote last edited by
    #1

    Hi all,
    When using KDE system settings, changing the style magically makes its way to all open applications so they load the new style.
    I made a custom QStyle which has its own config tool. I'd like to reproduce the notification when I press "Apply" button so that apps using my style will reload the config.
    How can I notify open apps for style (or config) changes ?

    1 Reply Last reply
    0
    • D Offline
      D Offline
      dextermagnific
      wrote last edited by
      #3

      Yes watching the config file is something that I intended to use as a fallback. Do the X server or Wayland support a "style change" message ?

      I found some time ago this code (that does not work):

      #if HAVE_X11
      void ThemeManagerUI::notifyConfigurationChange()
      {
        using namespace QNativeInterface;
        QX11Application *native = qApp->nativeInterface<QX11Application>();
      
        qDebug() << "FIXME notifyConfigurationChange()";
      
        QByteArray stamp;
        QDataStream s(&stamp, QIODevice::WriteOnly);
        s << QDateTime::currentDateTime();
      
        QByteArray settings_atom_name("_QT_SETTINGS_TIMESTAMP_");
        settings_atom_name += XDisplayString(native->display());
      
        xcb_connection_t *xcb_conn = native->connection();
        xcb_intern_atom_cookie_t cookie = xcb_intern_atom(xcb_conn, false, settings_atom_name.size(), settings_atom_name.constData());
        xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(xcb_conn, cookie, 0);
        xcb_atom_t atom = reply->atom;
        free(reply);
      
        xcb_change_property(xcb_conn, XCB_PROP_MODE_REPLACE, qApp->topLevelWindows().first()->winId(), atom, XCB_ATOM_ATOM,
                            8, stamp.size(), (const void *)stamp.constData());
      
        //XChangeProperty(QX11Info::display(), QX11Info::appRootWindow(0),
                        //ATOM(_QT_SETTINGS_TIMESTAMP), ATOM(_QT_SETTINGS_TIMESTAMP), 8,
                        //PropModeReplace, (unsigned char *)stamp.data(), stamp.size());
      }
      #endif
      

      I don't know the purpose of this QT_SETTINGS_TIMESTAMP. Maybe there is a similar one for style change.

      I 1 Reply Last reply
      0
      • I Offline
        I Offline
        IgKh
        wrote last edited by
        #2

        KDE does it through its QPA platform theme that it injects into all Qt applications running under it that use the same Qt installation as itself. It listens over D-Bus for settings changes.

        While you probably can't use the same mechanism for your needs, you can do something similar within your style implementation. For example, if the configuration tool writes out a settings file, you can use QFileSystemWatcher to monitor for changes to that file and re-load it. Or also use D-Bus, or any of the myriad of other IPC mechanisms available - all based on what makes sense for your design.

        1 Reply Last reply
        0
        • D Offline
          D Offline
          dextermagnific
          wrote last edited by
          #3

          Yes watching the config file is something that I intended to use as a fallback. Do the X server or Wayland support a "style change" message ?

          I found some time ago this code (that does not work):

          #if HAVE_X11
          void ThemeManagerUI::notifyConfigurationChange()
          {
            using namespace QNativeInterface;
            QX11Application *native = qApp->nativeInterface<QX11Application>();
          
            qDebug() << "FIXME notifyConfigurationChange()";
          
            QByteArray stamp;
            QDataStream s(&stamp, QIODevice::WriteOnly);
            s << QDateTime::currentDateTime();
          
            QByteArray settings_atom_name("_QT_SETTINGS_TIMESTAMP_");
            settings_atom_name += XDisplayString(native->display());
          
            xcb_connection_t *xcb_conn = native->connection();
            xcb_intern_atom_cookie_t cookie = xcb_intern_atom(xcb_conn, false, settings_atom_name.size(), settings_atom_name.constData());
            xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(xcb_conn, cookie, 0);
            xcb_atom_t atom = reply->atom;
            free(reply);
          
            xcb_change_property(xcb_conn, XCB_PROP_MODE_REPLACE, qApp->topLevelWindows().first()->winId(), atom, XCB_ATOM_ATOM,
                                8, stamp.size(), (const void *)stamp.constData());
          
            //XChangeProperty(QX11Info::display(), QX11Info::appRootWindow(0),
                            //ATOM(_QT_SETTINGS_TIMESTAMP), ATOM(_QT_SETTINGS_TIMESTAMP), 8,
                            //PropModeReplace, (unsigned char *)stamp.data(), stamp.size());
          }
          #endif
          

          I don't know the purpose of this QT_SETTINGS_TIMESTAMP. Maybe there is a similar one for style change.

          I 1 Reply Last reply
          0
          • D dextermagnific

            Yes watching the config file is something that I intended to use as a fallback. Do the X server or Wayland support a "style change" message ?

            I found some time ago this code (that does not work):

            #if HAVE_X11
            void ThemeManagerUI::notifyConfigurationChange()
            {
              using namespace QNativeInterface;
              QX11Application *native = qApp->nativeInterface<QX11Application>();
            
              qDebug() << "FIXME notifyConfigurationChange()";
            
              QByteArray stamp;
              QDataStream s(&stamp, QIODevice::WriteOnly);
              s << QDateTime::currentDateTime();
            
              QByteArray settings_atom_name("_QT_SETTINGS_TIMESTAMP_");
              settings_atom_name += XDisplayString(native->display());
            
              xcb_connection_t *xcb_conn = native->connection();
              xcb_intern_atom_cookie_t cookie = xcb_intern_atom(xcb_conn, false, settings_atom_name.size(), settings_atom_name.constData());
              xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(xcb_conn, cookie, 0);
              xcb_atom_t atom = reply->atom;
              free(reply);
            
              xcb_change_property(xcb_conn, XCB_PROP_MODE_REPLACE, qApp->topLevelWindows().first()->winId(), atom, XCB_ATOM_ATOM,
                                  8, stamp.size(), (const void *)stamp.constData());
            
              //XChangeProperty(QX11Info::display(), QX11Info::appRootWindow(0),
                              //ATOM(_QT_SETTINGS_TIMESTAMP), ATOM(_QT_SETTINGS_TIMESTAMP), 8,
                              //PropModeReplace, (unsigned char *)stamp.data(), stamp.size());
            }
            #endif
            

            I don't know the purpose of this QT_SETTINGS_TIMESTAMP. Maybe there is a similar one for style change.

            I Offline
            I Offline
            IgKh
            wrote last edited by
            #4

            @dextermagnific said in How to notify style change to apps ?:

            Do the X server or Wayland support a "style change" message

            No, neither knows anything about theming, styles or anything of the sort. The closest thing you have for a generic way is the XDG Settings Portal, and it only conveys changes of light/dark mode and high contrast mode.

            In X11 there used to be a generic Xsettings protocol, which the code you posted seems to be related to. I don't see how that helps you - applications have to listen and respond to it anyway; and it is X11 specific. If you want a push based approach rather than pull based you can create your own D-Bus interface. If you are worried that watching the configuration file is inefficient, don't be - inotify isn't polling.

            1 Reply Last reply
            0
            • D Offline
              D Offline
              dextermagnific
              wrote last edited by
              #5

              Thank you I'll go the inotify way. I just need to check that "commits" to the settings file are atomic so I won't be reading garbage (I read somewhere that QSettings handles well that).

              1 Reply Last reply
              0
              • D dextermagnific has marked this topic as solved

              • Login

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