Git Product home page Git Product logo

opengamepadui's People

Contributors

bell07 avatar j3ffrw avatar pastaq avatar semantic-release-bot avatar shadowapex avatar sschott avatar sterophonick avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opengamepadui's Issues

First run bootstrap

We need a user-friendly first run interface that will allow a user to configure the environment. Possible options include:

  • Connect to a network #27
  • Select and configure initial library plugins
  • Select and configure audio and Bluetooth devices #27
  • Configure cloud saving #49
  • Configure display settings
  • Configure language settings #62

Implement plugin settings UI

We should have a UI in our settings menu to manage plugins. We should be able to:

  • List installed plugins
  • Disable plugins
  • View plugin details
  • View available plugins from the plugin store

Proton Management

Users should be able to download/install Proton and ProtonGE as new versions are released. We should include interfaces for plugins to poll for configured versions and set their library items to a user selected proton version, or default to the globally set version from this Interface.

Write GDExtension for native XAtom methods

We currently rely on tools like xprop and xwininfo to retrieve and set XAtoms to tell Gamescope that OpenGamepadUI is an overlay, and where input focus should be. To remove these tools as a dependency, we should add these methods as a GDExtension and directly use the c++ library. Godot already relies on X11/Xatom.h, so it should be straightforward to expose these methods to GDScript.

Implement on-screen keyboard

We need to implement an on-screen keyboard to allow users to input text in-game and in menus.

For sending keyboard input to games, I know that xdotool supports this functionality until we can implement the methods natively using GDExtension.

Create virtual gamepad configuration interface

We're currently using libevdev to intercept gamepad input and direct it to a virtual gamepad. As a result, we should be able to allow users to customize their controller mappings, send virtual keypresses, etc.

Godot build fails with import errors

Per #1

Building fails and throws a ton of errors using either the Makefile or directly invoking a headless godot build.

Building on the target machine (Steam Deck) over ssh. Using newest Godot4 beta6 from AUR. Gamescope installed via pacman. Freshly cloned main branch as working directory.

Minor issue, but Makefile uses non-standard fixed paths to godot4 and gamescope binaries, so those needed to be modified to use system paths.

building invoked using both make build and directly using godot4 --headless --export "Linux" (per godot4 documentation) as well as trying godot4 --headless --export "Linux/X11". Seems to be the same issues in any case.

build.log via Makefile

Was only able to get it to build after repeatedly opening the project in the GUI editor :P

Implement interface to select game installation location

Currently OpenGamepadUI doesn't provide an API that can allow Library plugins to prompt the user where they would like games to be installed (e.g. installed on SD card vs internal disk). We should provide an API interface to allow users to select where to install games. Standardizing this interface could be difficult as different library providers may have different ways of storing games. At very least, we should give Library plugins an optional content box where they can populate an interface to select storage.

Add build and runtime requirements to readme

Hey dude,

I spent a little time today getting the main branch running. Already had both X11 and sway installed, then grabbed godot4-b6 from AUR, so those pull in their own dependencies, but opengamepad-ui cannot, nor does it list what it relies on.

From what I can see it looks like it needs wayland, gamescope, X11, xorg-xwayland, xcb, and probably others? I'm also assuming that it cannot be built with Godot < v4.0? Can we get a list of requirements?

Also, I don't have much experience with Godot, but is there a way to import assets and build this headlessly? I do pretty much everything over ssh, but godot refuses to build the project unless I run the editor in a GUI session even with the --headless option. I get a mountain of errors about assets need to be imported in the editor. After opening and closing the editor a few times it finally decided to import. Seems like there should be a way to automate that headlessly.

I'd really rather not ever need to run a huge GUI IDE just to build a binary if possible, haha

Implement theming and theme selection

Godot already supports theming. We should define the default theme and use that everywhere instead of doing per-element overrides. Then we can also add a settings menu to select different themes.

When exiting a Steam game normally, Steam continues to run, preventing us from detecting the game has closed

Detecting when games close is complex. Normally, when we launch a non-Steam game, we get the process ID of the thing we just launched, and can check if that PID has died. Easy peasy:

gamescope (pid 10)
  \---- opengamepadui (pid 11) - { I launched you with pid 12! }
          \---- game (pid 12)

Steam, however, doesn't make it easy for us. When you launch a Steam game, it launches a "steam launcher" script, where its whole job is to start up Steam and then die.

gamescope (pid 10)
  \---- opengamepadui (pid 11) - { I launched you with pid 12! }
          \---- steam (pid 12) - { Ok, time to die! }
                 \---- steam-for-real (pid 13)

This has the fantastic consequence of orphaning the real Steam process.

gamescope (pid 10)
  \---- opengamepadui (pid 11)
          \---- (defunct)
                 \---- steam-for-real (pid 13)

This is a common technique called double-fork, where a process will fork itself, and then die. It's a way to try and daemonize a process. When a process gets orphaned, the init process (pid 1) or a SUBREAPER becomes its new parent. In this case, gamescope takes the poor orphan in.

gamescope (pid 10)
  |---- opengamepadui (pid 11) - { Did the game just die? }
  \       \---- (defunct)
   \--- steam-for-real (pid 13)
          \---- game (pid 14)

We might actually be able to use subreaper ourselves to make Steam re-parent to us, which might make things a bit easier. But right now, to OGUI, it looks like the game just died. Luckily we have a few tricks to find where Steam went. Whenever we spawn a process, it also has a PGID or process group ID! We can use that to determine what decedents might still be hanging around.

gamescope (pid 10)
  |---- opengamepadui (pid 11) - { Hey wait, you still have children around! }
  \       \---- (defunct) (pid: 12, pgid: 12)
   \--- steam-for-real (pid 13, pgid: 12) 
          \---- game (pid 14, pgid: 12)

Great! Now we can find the decedents of our process we launched. If we want to exit a game, we can just kill all the decedents. That brings us to our next problem: Steam doesn't like to die. If game crashes or exits normally, Steam sticks around. There's not a super robust way to detect what the real game is.

gamescope (pid 10)
  |---- opengamepadui (pid 11) - { Hmmm, not sure if game, or just steam processes... }
  \       \---- (defunct) 
   \--- steam-for-real (pid 13, pgid: 12) 
          \---- (defunct)

There's a few things we could try:

  • Create a "blacklist" of Steam processes that we shouldn't consider a game.
    • Games might take a little while to launch, so Steam processes are all there will be until it launches. What if it never launches?
    • What if we just want to launch Steam by itself?
    • This is very Steam-specific and won't work with other launchers.
  • Look for STEAM_GAME window properties.
    • This is very Steam-specific and won't help us with other kinds of launchers.

???

Implement Quick Access Menu

We should have a UI for a quick access menu that users can use in-game to adjust common and game-specific settings.

BUG: opengamepadui crashes after changing library tabs

OpengamepadUI will crash if your library is still loading and you swtich from "all games" to another tab. Unsure if this is a LibraryManager bug or a opengamepadui-steam bug.

================================================================
handle_crash: Program crashed with signal 11
Engine version: Godot Engine v4.0.rc1.official (8843d9ad347e5c3be5130153aeecdf48e4fe5a14)
Dumping the backtrace. Please include this when reporting the bug to the project developer.
[1] /usr/lib/libc.so.6(+0x38f50) [0x7fbdd7874f50] (??:0)
[2] /usr/bin/godot4() [0x125fb52] (??:0)
[3] /usr/bin/godot4() [0x117698f] (??:0)
[4] /usr/bin/godot4() [0x4555f6b] (??:0)
[5] /usr/bin/godot4() [0x438ee84] (??:0)
[6] /usr/bin/godot4() [0x458a04a] (??:0)
[7] /usr/bin/godot4() [0x2dcd838] (??:0)
[8] /usr/bin/godot4() [0x458a04a] (??:0)
[9] /usr/bin/godot4() [0x2dc6b61] (??:0)
[10] /usr/bin/godot4() [0xea091b] (??:0)
[11] /usr/bin/godot4() [0x45590e6] (??:0)
[12] /usr/bin/godot4() [0x458ba8e] (??:0)
[13] /usr/bin/godot4() [0x124ef78] (??:0)
[14] /usr/bin/godot4() [0x117698f] (??:0)
[15] /usr/bin/godot4() [0x2b6f05c] (??:0)
[16] /usr/bin/godot4() [0x2bcf6c2] (??:0)
[17] /usr/bin/godot4() [0x2bcffab] (??:0)
[18] /usr/bin/godot4() [0x2bece25] (??:0)
[19] /usr/bin/godot4() [0xe7e58a] (??:0)
[20] /usr/bin/godot4() [0x431cf34] (??:0)
[21] /usr/bin/godot4() [0x431e055] (??:0)
[22] /usr/bin/godot4() [0xe7eee7] (??:0)
[23] /usr/bin/godot4() [0xdf2252] (??:0)
[24] /usr/lib/libc.so.6(+0x23790) [0x7fbdd785f790] (??:0)
[25] /usr/lib/libc.so.6(__libc_start_main+0x8a) [0x7fbdd785f84a] (??:0)
[26] /usr/bin/godot4() [0xe1234e] (??:0)
-- END OF BACKTRACE --
================================================================
connection handler failed
Traceback (most recent call last):
  File "/home/blip/.pex/installed_wheels/a1b6b65cec48f201c6eec25be6abbee9fd40c9bd1892e2f4d4890f51183dd672/websockets-10.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl/websockets/legacy/protocol.py", line 968, in transfer_data
    message = await self.read_message()
  File "/home/blip/.pex/installed_wheels/a1b6b65cec48f201c6eec25be6abbee9fd40c9bd1892e2f4d4890f51183dd672/websockets-10.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl/websockets/legacy/protocol.py", line 1038, in read_message
    frame = await self.read_data_frame(max_size=self.max_size)
  File "/home/blip/.pex/installed_wheels/a1b6b65cec48f201c6eec25be6abbee9fd40c9bd1892e2f4d4890f51183dd672/websockets-10.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl/websockets/legacy/protocol.py", line 1113, in read_data_frame
    frame = await self.read_frame(max_size)
  File "/home/blip/.pex/installed_wheels/a1b6b65cec48f201c6eec25be6abbee9fd40c9bd1892e2f4d4890f51183dd672/websockets-10.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl/websockets/legacy/protocol.py", line 1170, in read_frame
    frame = await Frame.read(
  File "/home/blip/.pex/installed_wheels/a1b6b65cec48f201c6eec25be6abbee9fd40c9bd1892e2f4d4890f51183dd672/websockets-10.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl/websockets/legacy/framing.py", line 69, in read
    data = await reader(2)
  File "/usr/lib/python3.10/asyncio/streams.py", line 705, in readexactly
    raise exceptions.IncompleteReadError(incomplete, n)
asyncio.exceptions.IncompleteReadError: 0 bytes read on a total of 2 expected bytes

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/blip/.pex/installed_wheels/a1b6b65cec48f201c6eec25be6abbee9fd40c9bd1892e2f4d4890f51183dd672/websockets-10.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl/websockets/legacy/server.py", line 236, in handler
    await self.ws_handler(self)
  File "/home/blip/.pex/installed_wheels/a1b6b65cec48f201c6eec25be6abbee9fd40c9bd1892e2f4d4890f51183dd672/websockets-10.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl/websockets/legacy/server.py", line 1175, in _ws_handler
    return await cast(
  File "/home/blip/.local/share/opengamepadui/scripts/steam/server.py", line 146, in main
    async for message in websocket:
  File "/home/blip/.pex/installed_wheels/a1b6b65cec48f201c6eec25be6abbee9fd40c9bd1892e2f4d4890f51183dd672/websockets-10.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl/websockets/legacy/protocol.py", line 497, in __aiter__
    yield await self.recv()
  File "/home/blip/.pex/installed_wheels/a1b6b65cec48f201c6eec25be6abbee9fd40c9bd1892e2f4d4890f51183dd672/websockets-10.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl/websockets/legacy/protocol.py", line 568, in recv
    await self.ensure_open()
  File "/home/blip/.pex/installed_wheels/a1b6b65cec48f201c6eec25be6abbee9fd40c9bd1892e2f4d4890f51183dd672/websockets-10.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl/websockets/legacy/protocol.py", line 944, in ensure_open
    raise self.connection_closed_exc()
websockets.exceptions.ConnectionClosedError: no close frame received or sent
https://aur.archlinux.org/packages/opengamepadui-session-gitThe XKEYBOARD keymap compiler (xkbcomp) reports:
> Warning:          Unsupported maximum keycode 708, clipping.
>                   X11 cannot support keycodes above 255.
The XKEYBOARD keymap compiler (xkbcomp) reports:
> Warning:          Unsupported maximum keycode 708, clipping.
>                   X11 cannot support keycodes above 255.
Errors from xkbcomp are not fatal to the X server
Errors from xkbcomp are not fatal to the X server
^Cgamescope: received kill signal, terminating!
xwm: Lost connection to the X11 server 0
xwm: X11 I/O error

Localization options

We need a way to change the default language of the interface based on user selection and/or OS settings.

Allow sharing of per-game power profiles, gamepad profiles, etc.

One of the great features that Steam has is the ability for the community to create and share gamepad profiles. This would be a great feature for OpenGamepadUI, but may be challenging to implement. Valve stores these profiles and shares them using their own server infrastructure, of which we do not have for OpenGamepadUI.

Challenges

  • OpenGamepadUI has no real infrastructure for users to upload/download profiles from.
  • Some kind of curation is needed to filter out user profiles that might have offensive content.
  • Users should be able to easily upload and download user profiles.
  • Users should be able to vote/rank user profiles.

Ideas

GitHub Repository

A solution could be to have a GitHub repository that users could make pull requests to with per-game profiles, similar to how the current plugin store is implemented.

Some benefits would be:

  • GitHub hosts this data for us at no cost.
  • PRs can be reviewed for bad or offensive content.

Some problems with this solution are:

  • Users won't be able to upload profiles from the UI.
  • Creating PRs requires a certain level of technical knowledge.
  • Users won't be able to vote on profiles.

P2P Decentralized storage

Another potential solution could be trying to use peer-to-peer sharing with something like IPFS to share custom profiles.

Some benefits would be:

  • Users share their profiles directly, without requiring dedicated hosting
  • Users could upload profiles directly from OpenGamepadUI

Some problems with this solution:

  • Curating profiles might be a technical challenge.
  • Voting system might be a technical challenge.

Support better touch scrolling

Currently touch-and-drag is supported to scroll through scroll containers, but only if you touch somewhere inside a scroll container that doesn't have a UI element. This makes touch scrolling a really bad experience.

Touch scroll events should be detected and passed to the scroll container.

Allow users to select the library launcher to use when launching a game

OGUI has the concept of Library Providers. These are systems which can provide a LibraryLaunchItem which describes how to launch a particular game. Sometimes you may have multiple Library providers that can provide a way to launch the same game. We should allow the user to configure which Library provider should be used to launch a particular game.

ProtonDB Query

We should define an interface that will query ProtonDB when provided a title and return basic information to the requesting plugin. It should also support iconography for platinum/gold/silver/borked/untested.

Opening side menus (main/QAM) shows the home menu behind the current menu

When on any menu other than home (e.g. Library, Settings, etc.), and you open up the main menu or QAM, the home menu is shown behind the current menu:

image

This is due to how VisibilityManager is implemented, which has a visible_during property that allows menus to be visible when the main menu, qam, and OSK are being shown.

One potential way this could be fixed could be to use a separate StateMachine for these overlay menus (main menu, qam, and OSK). We would just need some mechanism to re-focus the current menu when no states remain in the overlay menu state machine.

Implement plugin store

We should create a new repository that will act as the index for the plugin store. It should contain a JSON file that acts as the plugin store registry that points to available plugins.

It should look something like this:

{
  "plugins": [
    {
      "plugin.id": "flathub",
      "plugin.name": "FlatHub",
      "plugin.version": "1.0.0",
      "plugin.min-api-version": "1.0.0",
      "plugin.link": "https://github.com/ShadowBlip/OpenGamepadUI-flathub-plugin",
      "plugin.source": "https://github.com/ShadowBlip/OpenGamepadUI-flathub-plugin",
      "plugin.description": "FlatHub frontend for OpenGamepadUI",
      "plugin.archive": "https://github.com/ShadowBlip/OpenGamepadUI-flathub-plugin/refs/download/flathub-plugin-1.0.0.zip",
      "plugin.sha256": "b7bef0ae7dc06be5c1b7a8f35ff57ef932f3a1c7a1e8fe5aaf97c3d73d84edf2"
      "store.tags": ["flatpak", "flathub"],
      "store.images": ["https://path/to/image.png"],
      "author.name": "William Edwards",
      "author.email": "[email protected]",
    }
  ]
}

Users can add their plugin to the store by opening a pull request to this repo, and can be added after review and verification.

SDL2 Support

It would be nice to have the ability to use SDL2 mappings for unusual gamepads. Via plugin or a direct implementation. Here is what I'm referring to btw. Not to be confused with another project with a similar name.

Implement settings and settings UI

We need to implement a settings manager and user interface to load and save user settings. This should probably be a singleton which all nodes can access for global settings.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.