Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-102346

QIcon theme revamp

    XMLWordPrintable

Details

    • Task
    • Resolution: Unresolved
    • P3: Somewhat important
    • None
    • Some future release
    • GUI: Look'n'Feel
    • None
    • All
    • 5ae635548 (dev), d2e163d2e (dev), f54393ba7 (dev), f18fcb6be (dev), 4bce81b03 (dev)

    Description

      The QIcon theme machinery/APIs/docs could use some revamp. The original design was based on the freedesktop icon spec, but we should not limit ourselves to that. For example, macOS 11+ now has a comprehensive icon set known as SF Symbols, Windows provides font-based icons sets (the
      Segoe MDL2 Assets on Windows 10, Segoe Fluent Icons on Windows 11) that are pre-installed on the system, and Google provides a set of icon fonts (that are not pre-installed on all Android systems) within the Material design system, both as non-variable fonts, and as variable fonts with various axis.
        * https://developer.apple.com/sf-symbols/

      The system icon infrastructure on modern platforms provides more than "static graphics based on an identifier":

      • different platform icon variations that an application can select (such as filled or outlined)
      • with variable fonts, applications can configure the OpenType axis (weight, FILL, GRAD, opsz)
      • icons can be requested in different colours and with different coloring mechanisms
      • in Apple's infrastructure, icons are multi-layered, and a "variable" value (a double between 0 and 1) can be used to select which layers to draw

      The icons provided by these system APIs are vector glyphs, and monochrome; some "multicolour" icons exist, but even those are using just a handful of colours. None of the APIs listed above provide icons as pixmaps. The freedesktop icon spec has not been updated since 2006:

      KDE's KIconTheme is using SVG and applies coloring dynamically based on the global palette/color scheme.

      Status quo

      The current API allows us to create a theme-based QIcon via QIcon::fromTheme, which takes a string that is interpreted by the QIconEngine implementation that ends up being used (see the "Current architecture" section below for the details how a QIconEngine implementation is selected).

      QIcon has various static APIs to select themes and fallback themes (such as QIcon::setThemeName); those APIs are tightly coupled to the freedesktop standard and the notion that themes are meta-data files that map individual named icons to sets of pixmaps. As of now, a native icon engine (as provided by QPlatformIntegration::createIconEngine) will not be used if a theme is set.

      Goals

      • We want a cross-platform API that produces the native QIcon representing the requested symbol

      Taking the current API as a starting point:

      QIcon clearIcon = QIcon::fromTheme("clear"); 

      should produce the icon for a "clear" action (i.e. to clear input in a line edit or similar) from the native icon library.

      • Applications should be able to define those attributes of icons that can be expected to be the same for all icons, without having to configure each QIcon individually

      E.g. a "filled" icon theme should be used for all icons.

      This is conceptually similar from setting the "theme" via QIcon::setThemeName. On KDE, you can select "oxygen" vs "breeze"; on macOS you could select "filled" vs "outlined". If a different theme is wanted during runtime, then applications can be expected to recreate the icons after making the change.

      • We want to provide access to the native capabilities through a cross-platform API

      Attributes that are not supported by the underlying system are either ignored or emulated

      • Some attributes, like the "variable value" attribute, should be usable with an icon instance

      The application can change that attribute on an existing icon, without requesting a completely new icon.

      These attributes could be a property of the icon, or only a passthrough-value when requesting the pixmap (like state and mode are today; those are not properties of the icon, the icon contains pixmaps for all combinations).

      • Coloring should respect the application palette by default, but be overridable by the control using the icon

      Without doing anything, icons should use the global foreground color, i.e. have the same color as text, and adapt dynamically to dark and light color schemes. However, individual controls should be able to override this and request the icon with a different "tinting" or colorisation mode (Apple supports a variety of coloring modes; font-based systems can just draw the entire glyph with the a specific color).

       

      Some steps/ideas:

      • Let the string based QIcon::fromTheme look up the strings directly in the underlying theme. On freedesktop platforms that will be 1:1 with what we have today. On macOS the names from SF Symbols will be mapped.
        • This behavior change should be fine, as no non-freesktop platform implements this today anyways
        • Disadvantage: this is not cross platform; the Apple symbol "doc.badge.plus" does not exist on other platforms, and would be the "document-new" icon in the freedesktop standard. Applications would have to use #ifdef to specify the icon, or use a chain of fallback icons.
        • Disadvantage: on Android and Windows, the icons are identified by a single code point in the font, not a full name
      • Interpret the QIcon::themeName with some structure
        • e.g. if the theme name is "system", use the platform theme; allow specifying "theme variations" via syntax - "system.filled" uses the "filled" system icons
        • use something similar to the the CSS or URL syntax for font attributes: Yuck, but for reference:
      <style>
      .material-symbols-outlined {
        font-variation-settings:
        'FILL' 0,
        'wght' 400,
        'GRAD' 0,
        'opsz' 40
      }
      </style> 
      
      <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />

       

      • Add a QIcon::StandardIcon enum and fromTheme overload that matches the existing freedesktop spec, mapping to the same names on freedestkop platforms, and to the relevant names on SF Symbols.
        • Align with QStyle::StandardPixmap
        • This allows us to cheaply map from enum value to symbol identifier on each platform, and makes it easy to write platform independent code. "QIcon:StandardIcon:DocumentNew" would map to "document-new" on freedesktop, to "doc.badge.plus" on Apple, and to a matching glyph on Windows and Android.
      • Guard the QIconCacheGtkReader behind a GTK configure ifdef, or possibly move to the Gtk3 platform theme if possible

      Current architecture

      • Individual QIcons backed by a QIconEngine
        • One icon/engine per "named icon" (e.g. document-new), but supporting multiple resolutions and states
      • Themed icon lookups via QIcon::fromTheme
        • Allows platform specific icon theme backends via QPlatformTheme::createIconEngine
        • Otherwise falls back to QIconLoaderEngine
          • Which in turn pulls out the icons during drawing from QIconLoader
        • QIconLoader is the machinery that provides all the fallback logic and search paths exposed via QIcon
          • If a platform plugin implements QPlatformTheme::createIconEngine none of this machinery is involved
        • Two levels of caching
          • General QIcon cache in qtIconCache()
            • Results in repeated requests to fromTheme("document-new) returning the same QIcon
          • QIconLoaderEngine detects changes to the QIconLoader theme (name change e.g.), via QIconLoader::invalidateKey()
            • Results in existing QIcons returned from fromTheme("document-new") automatically picking up new theme
      • Poorly documented interaction between QIcon::fromTheme (added in 4.6 / 13a31fe82845f8b1f4d86919080d3b2a87c4d061), the QPlatformTheme::createIconEngine hook (added in 5.1 / https://codereview.qt-project.org/c/qt/qtbase/+/46458), and the fallback logic e.g. fallbackThemeName (added in 5.12 / https://codereview.qt-project.org/c/qt/qtbase/+/237025)

      Related issues

      https://bugreports.qt.io/issues/?jql=text%20~%20%22QIcon%3A%3AfromTheme%22%20and%20status%20not%20in%20(closed)

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              vhilshei Volker Hilsheimer
              vestbo Tor Arne Vestbø
              Votes:
              0 Vote for this issue
              Watchers:
              14 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews