ylorant / splitty

Tiny speedrun timer made in HTML5 and Javascript
MIT License
24 stars 6 forks source link

Global hotkeys / Gamepad support #10

Open thejoshwolfe opened 8 years ago

thejoshwolfe commented 8 years ago

Global hotkeys are often essential for a speedrun timer. If you're running the timer in the same OS as the game you're speedrunning, you need to be able to split without the game window losing focus. As a developer familiar with the web philosophy, I can pretty confidently predict that global hotkeys will never be a web standard feature due to the security implications.

However, there are elaborate ways to accomplish global hotkey support, albeit very, very complicated. This isn't entirely in the domain of this project, but I thought I'd open a discussion thread here for anyone who is interested in both this project and this topic.

Inspired by some googling, here's one strategy that can get the job done:

  1. Install and run a native program in your OS that can respond to global hotkeys.
  2. Install a plugin/extension in your webbrowser that interacts with Splitty.

A chrome extension can be given permissions to make cross-origin requests, which means the extension can be listening to a server running on localhost. That server could be the native program mentioned above that is also listening for OS native global hotkeys. The sequence of events would then be this:

  1. User presses the global hotkey.
  2. Native app responds by sending a notification to the browser extension
  3. Browser extension tells Splitty to split.
  4. Splitty splits.

The relevance of this discussion in this project is that the Splitty team could provide official programs that fill each of those roles (probably as separate github repos). Splitty would, however, need an API for the chrome extension to use for step 3 above.

ylorant commented 7 years ago

Thanks for rising a discussion here about this subject.

Indeed, the problem with global hotkeys is a big one, since it basically bans people from using Splitty while running on the same machine (except in a few cases, but that's not the point). I encountered this problem myself for some time, but since I'm trying to move my runs to console and since I don't run PC games I did not bother until recently (about a month I'll say, because of a new game I plan to run, mainly).

This problem could be partly solved (at least for some people, including me, playing on like an emulator) by using the gamepad to split with an unused button (or a button on another gamepad). I know this is not a complete solution to the problem, but that's a little step in the right way, and a solution to another problem where people splitting with gamepads could not use Splitty since it didn't support that. I've started to implement it using Javascript's Gamepad API, and have implemented the update in the storage system I mentioned in issue #9 since I needed to store additional settings.

For a final solution, the one you provided is a good one, albeit being a little complicated (the user would have to install a native program + a chrome/firefox extension, and that could be bothering).

I've searched a bit for an easier way to solve this problem, and I've come across this post on SO giving the code allowing the creation of an extension exposing a shortcut, and with that, Chrome has apparently added support for global hotkeys in its extensions/apps. I think more investigation is needed on this path, to see if a solution using only an extension is possible.

If the solution explained above isn't possible, I think we could do without installing an extension, just by implementing a websocket client/server system between a native app and the timer inside its tab. Another solution would be to implement the timer in its entirety with Electron like OstlerDev did, but that would defy the concept of the timer just being in the browser... (although the cross-platform part would be kept).

ylorant commented 7 years ago

Just a little update to say that I just added basic gamepad support. That would be great if some people tried it to check that everything is correct. I did some tests myself and everything seems to work.