| @@ -18,8 +18,35 @@ | ||
| 18 | 18 | |
| 19 | 19 | defined( 'ABSPATH' ) || exit; |
| 20 | 20 | |
| 21 | 21 | /** |
| 22 | + * The stylesheet handles a game window needs, hub or no hub. | |
| 23 | + * | |
| 24 | + * Set once while the Games window is registered — after the | |
| 25 | + * `openstation_games_window_args` filter, so it includes the built-in | |
| 26 | + * games' own sheets and any a plugin appended — and read back when the | |
| 27 | + * shell config is assembled. | |
| 28 | + * | |
| 29 | + * These ride the hub window as companion styles, which is right when | |
| 30 | + * the hub is what opened. It is not the only way in: the challenge | |
| 31 | + * toast's "Accept & Play" is built to work with the hub closed, solo | |
| 32 | + * mode boots straight to `?openstation_solo=os-game-<id>`, and | |
| 33 | + * `wp.os.games.launch()` is documented for plugin authors. Each of | |
| 34 | + * those reaches `launchGame()` in the shell bundle without the hub | |
| 35 | + * window ever existing, and the game then paints unstyled. | |
| 36 | + * | |
| 37 | + * @param string[]|null $set Handles to store, when registering. | |
| 38 | + * @return string[] The stored handles. | |
| 39 | + */ | |
| 40 | +function openstation_games_style_handles( $set = null ) { | |
| 41 | + static $handles = array(); | |
| 42 | + if ( null !== $set ) { | |
| 43 | + $handles = array_values( array_unique( array_filter( array_map( 'strval', (array) $set ) ) ) ); | |
| 44 | + } | |
| 45 | + return $handles; | |
| 46 | +} | |
| 47 | + | |
| 48 | +/** | |
| 22 | 49 | * The shared gamepad SVG used by the window icon and the desktop |
| 23 | 50 | * icon. |
| 24 | 51 | * |
| 25 | 52 | * Drawn in `currentColor`, which is what makes it a silhouette: |
| @@ -125,8 +152,15 @@ | ||
| 125 | 152 | 'title' => __( 'Games', 'desktop-mode' ), |
| 126 | 153 | 'icon' => $icon_uri, |
| 127 | 154 | 'template' => 'openstation_games_render_template', |
| 128 | 155 | 'script' => 'desktop-mode-games', |
| 156 | + // Companion styles load with the games bundle on first open. | |
| 157 | + // Every game window (`os-game-<id>`) is opened by | |
| 158 | + // `launchGame()`, which lives in that bundle — so a sheet | |
| 159 | + // riding it here is guaranteed in the tab before any game | |
| 160 | + // paints. Built-in games append their own via the | |
| 161 | + // `openstation_games_window_args` filter below. | |
| 162 | + 'styles' => array( 'desktop-mode-games' ), | |
| 129 | 163 | 'width' => 900, |
| 130 | 164 | 'height' => 600, |
| 131 | 165 | 'min_width' => 560, |
| 132 | 166 | 'min_height' => 400, |
| @@ -146,8 +180,20 @@ | ||
| 146 | 180 | * @param array $window_args Args passed to `openstation_register_window()`. |
| 147 | 181 | */ |
| 148 | 182 | $window_args = (array) apply_filters( 'openstation_games_window_args', $window_args ); |
| 149 | 183 | |
| 184 | + // Remember the finished style list — base sheet plus whatever the | |
| 185 | + // built-in games and any plugin appended through the filter above. | |
| 186 | + // A game window does NOT always arrive through the hub: the | |
| 187 | + // challenge toast's "Accept & Play" is designed to work with the | |
| 188 | + // hub closed, solo mode boots straight into | |
| 189 | + // `?openstation_solo=os-game-<id>`, and `wp.os.games.launch()` is | |
| 190 | + // documented for plugins. In each of those, `launchGame()` runs | |
| 191 | + // from the SHELL bundle's copy, the hub window never opens, and its | |
| 192 | + // companion sheets never load — the HUD paints as raw text. The | |
| 193 | + // shell needs the list to inject them on demand. | |
| 194 | + openstation_games_style_handles( $window_args['styles'] ); | |
| 195 | + | |
| 150 | 196 | $registered = openstation_register_window( 'desktop-mode-games', $window_args ); |
| 151 | 197 | if ( is_wp_error( $registered ) ) { |
| 152 | 198 | // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log |
| 153 | 199 | error_log( '[openstation] Games window registration failed: ' . $registered->get_error_message() ); |
| @@ -192,8 +238,9 @@ | ||
| 192 | 238 | 'challengesUrl' => esc_url_raw( rest_url( 'desktop-mode/v1/games/challenges' ) ), |
| 193 | 239 | 'usersSearchUrl' => esc_url_raw( rest_url( 'desktop-mode/v1/games/users/search' ) ), |
| 194 | 240 | ) |
| 195 | 241 | ); |
| 196 | - | |
| 197 | - wp_enqueue_style( 'desktop-mode-games' ); | |
| 198 | 242 | } |
| 199 | -add_action( 'admin_enqueue_scripts', 'openstation_games_localize_config', 30 ); | |
| 243 | +// Priority 5 for the same reason as the recycle bin: the lazy-load payload is | |
| 244 | +// built at priority 10, and localize data attached after that never reaches a | |
| 245 | +// bundle that loads on window open. | |
| 246 | +add_action( 'admin_enqueue_scripts', 'openstation_games_localize_config', 5 ); | |