Skip to content

Game mode detection for Linux #2265

Closed
Closed

Description

@martinrotter

@martinrotter This could be adapted for linux, Feral Gamemode is a well-established equivalent.

Originally posted by @43v204ug in #1230

Activity

  1. added this to the 5.1.3 milestone on May 11, 2026
  2. self-assigned this
    on May 11, 2026
  3. martinrotter commented on May 12, 2026

    @martinrotter
    OwnerAuthor

    OK, it is implemented, but UNtested yet.

    Can you test yourself? Wait 30 minutes, until devbuild compiles and then test via AppImage.

    @43v204ug

  4. guihkx commented on May 12, 2026

    @guihkx
    Contributor

    I haven't tested the current implementation, and I know you're not a big fan of D-Bus, but I believe this can be a much simpler implementation based on a single D-Bus call.

    # initial query when no gamemode clients are active
    $ qdbus6 com.feralinteractive.GameMode /com/feralinteractive/GameMode com.feralinteractive.GameMode.ClientCount
    0
    # now we run vkcube through gamemoderun
    $ gamemoderun vkcube & disown
    # now we query again and it should return the number of active clients (in this case, 1)
    $ qdbus6 com.feralinteractive.GameMode /com/feralinteractive/GameMode com.feralinteractive.GameMode.ClientCount
    1

    Now all you'd have to do is implement that in C++/Qt, but hopefully it's not too hard...

  5. martinrotter commented on May 12, 2026

    @martinrotter
    OwnerAuthor
  6. martinrotter commented on May 12, 2026

    @martinrotter
    OwnerAuthor

    So far I left all implementations there

    DBus > library call > direct executable test

    we need to somehow test it by someone and then i will likely remove the library call part and only keep DBus and fallback ?

  7. guihkx commented on May 12, 2026

    @guihkx
    Contributor

    Yeah, I can test this.

    First though, I just want to check if these 3 different implementations don't lead to the same final path (a D-Bus call). I'll do some testing and I'll report back.

  8. guihkx commented on May 12, 2026

    @guihkx
    Contributor

    Okay, so it indeed seems like they're all relying on D-Bus in the end.

    The gamemode_query_status symbol you call here:

    reinterpret_cast<GameModeQueryStatusFn>(game_mode_library.resolve("gamemode_query_status"));

    Calls D-Bus at the end:

    1. https://github.com/FeralInteractive/gamemode/blob/bda6073db57cc797be16e1ae64350602b732e655/lib/gamemode_client.h#L310-L325
    2. https://github.com/FeralInteractive/gamemode/blob/bda6073db57cc797be16e1ae64350602b732e655/lib/client_impl.c#L378-L381
    3. https://github.com/FeralInteractive/gamemode/blob/bda6073db57cc797be16e1ae64350602b732e655/lib/client_impl.c#L299-L357

    The second implementation via cli, which relies on the output of gamemoded -s, also relies on D-Bus (I checked with dbus-monitor):

    method call time=1778574595.360466 sender=:1.529 -> destination=com.feralinteractive.GameMode serial=2 path=/com/feralinteractive/GameMode; interface=com.feralinteractive.GameMode; member=QueryStatusByPIDFd
       file descriptor
             inode: 163898
             type:    file descriptor
             inode: 163898
             type: method return time=1778574595.360966 sender=:1.0 -> destination=:1.529 serial=59 reply_serial=2
       int32 0
    

    So I guess I'd recommend just keeping the last implementation, which is shorter and it helps the Flatpak package too, because I won't need to package the GameMode binary/library for this to work...

    Alternatively, if you want to keep all of them, prioritize the one that makes the direct D-Bus call. (I just saw that you've already done that).

    I'll just wait for the CI to pass and then I'll test with the AppImage.

  9. martinrotter commented on May 12, 2026

    @martinrotter
    OwnerAuthor

    I see. Let me clean it up.

  10. martinrotter commented on May 12, 2026

    @martinrotter
    OwnerAuthor
  11. guihkx commented on May 12, 2026

    @guihkx
    Contributor

    I just tested with ee9f4f2, but it's not working and I think I know why:

    time="    20.436" type="debug" -> core: Game mode: DBus ClientCount query failed: 'Unknown method ClientCount or interface com.feralinteractive.GameMode.'
    

    ClientCount is a property, not a method:

    $ busctl --user introspect com.feralinteractive.GameMode /com/feralinteractive/GameMode
    NAME                                TYPE      SIGNATURE RESULT/VALUE FLAGS
    com.feralinteractive.GameMode       interface -         -            -
    .ListGames                          method    -         a(io)        -
    .QueryStatus                        method    i         i            -
    .QueryStatusByPID                   method    ii        i            -
    .QueryStatusByPIDFd                 method    hh        i            -
    .RefreshConfig                      method    -         i            -
    .RegisterGame                       method    i         i            -
    .RegisterGameByPID                  method    ii        i            -
    .RegisterGameByPIDFd                method    hh        i            -
    .UnregisterGame                     method    i         i            -
    .UnregisterGameByPID                method    ii        i            -
    .UnregisterGameByPIDFd              method    hh        i            -
    .ClientCount                        property  i         0            emits-change
    .GameRegistered                     signal    io        -            -
    .GameUnregistered                   signal    io        -            -
    org.freedesktop.DBus.Introspectable interface -         -            -
    .Introspect                         method    -         s            -
    org.freedesktop.DBus.Peer           interface -         -            -
    .GetMachineId                       method    -         s            -
    .Ping                               method    -         -            -
    org.freedesktop.DBus.Properties     interface -         -            -
    .Get                                method    ss        v            -
    .GetAll                             method    s         a{sv}        -
    .Set                                method    ssv       -            -
    .PropertiesChanged                  signal    sa{sv}as  -            -
    

    So instead of doing this:

    const QDBusReply<int> reply = game_mode.call(QSL("ClientCount"));
    if (!reply.isValid()) {
    qDebugNN << LOGSEC_CORE
    << "Game mode: DBus ClientCount query failed:" << QUOTE_W_SPACE_DOT(reply.error().message());
    return std::nullopt;
    }
    qDebugNN << LOGSEC_CORE << "Game mode: DBus client count is" << QUOTE_W_SPACE_DOT(reply.value());

    I think you need to do this instead (untested):

      QVariant client_count_variant = game_mode.property(QSL("ClientCount"));
    
      if (!client_count_variant.isValid()) {
        qDebugNN << LOGSEC_CORE
                 << "Game mode: Failed to read ClientCount property.";
        return std::nullopt;
      }
    
      const int client_count = client_count_variant.toInt();
    
      qDebugNN << LOGSEC_CORE << "Game mode: DBus client count is" << QUOTE_W_SPACE_DOT(client_count);
  12. martinrotter commented on May 12, 2026

    @martinrotter
    OwnerAuthor
  13. guihkx commented on May 12, 2026

    @guihkx
    Contributor

    Hmm, I don't see any messages about Game Mode in logs now, and auto-fetch at startup still occurs when GameMode is active and has clients.

    I made sure to enable the option in RSS Guard's settings as well:

    Image

    Here are the logs: https://pastebin.com/raw/BaBdNDiz

    This is the Qt6 text AppImage build based on f121c4f

  14. martinrotter commented on May 12, 2026

    @martinrotter
    OwnerAuthor

    i will test myself.

  15. martinrotter commented on May 12, 2026

    @martinrotter
    OwnerAuthor

    Latest master:

    time="    67.028" type="debug" -> core: Game mode: DBus client count is '5'.
    time="    67.028" type="warning" -> core: Feed auto-fetch is delayed because Game Mode is active.
    time="    68.028" type="debug" -> core: Game mode: DBus client count is '5'.
    time="    68.028" type="warning" -> core: Feed auto-fetch is delayed because Game Mode is active.
    time="    69.028" type="debug" -> core: Game mode: DBus client count is '5'.
    time="    69.028" type="warning" -> core: Feed auto-fetch is delayed because Game Mode is active.
    time="    70.028" type="debug" -> core: Game mode: DBus client count is '5'.
    time="    70.028" type="warning" -> core: Feed auto-fetch is delayed because Game Mode is active.
    

    If the checkbox in settings is NOT disabled, then it means the Gamemode is available (there is a runtime check).

    I checked the box and debugged all functions related to it and it works.

  16. guihkx commented on May 12, 2026

    @guihkx
    Contributor

    Ah, I think I understand why it didn't work for me; I only tested the auto-fetch at startup, I didn't try to manually fetch or wait for the 15 min auto-fetch.

    But now I tested it and it works. But maybe this can be expanded to auto-fetch on startup as well?

  17. martinrotter commented on May 12, 2026

    @martinrotter
    OwnerAuthor
  18. guihkx commented on May 12, 2026

    @guihkx
    Contributor

    Awesome, thanks!

  19. added a commit that references this issue on Jun 5, 2026
    ee9f4f2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Status-FixedTicket is resolved.Type-EnhancementThis is request for brand new feature.

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions