From 60324a7b2c58eb9e4fd177022dc162c8659e816a Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Sun, 10 Nov 2019 01:33:39 +0000 Subject: [PATCH] steam - special workaround for bad steam games so they match desktops many steam games don't provide much in properites - not enough to match to a desktop file. the only thing that actually consistently works is to use the STEAM_GAME property and match thyat to the uri provided to the steam command in the exec of the desktop file. this actually can work. nothing else works reliably across the board. and man can games be horrible and playing nice with desktops and having poor properties. even steam itself is not good. i had to add a workaround for that too to match steam-runtime explicitly. :( --- src/bin/e_client.c | 33 ++++++++++++++++++++++++++++++++- src/bin/e_client.h | 4 ++++ src/bin/e_comp_x.c | 8 ++++++++ src/bin/e_hints.c | 20 ++++++++++++++++++++ src/bin/e_hints.h | 3 +++ 5 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/bin/e_client.c b/src/bin/e_client.c index c1d84835b..2b2bcf696 100644 --- a/src/bin/e_client.c +++ b/src/bin/e_client.c @@ -2193,6 +2193,29 @@ _e_client_eval(E_Client *ec) ec->desktop = d; } } + if (!ec->desktop) + { + if (ec->steam.steam_game_id) + { + Efreet_Desktop *d; + Eina_List *desks = efreet_util_desktop_name_glob_list("*"); + EINA_LIST_FREE(desks, d) + { + if (!d->exec) continue; + if (!strncmp(d->exec, "steam ", 6)) + { + const char *st = strstr(d->exec, "steam://rungameid/"); + if (st) + { + st += strlen("steam://rungameid/"); + unsigned int id = atoi(st); + if (id == ec->steam.steam_game_id) + ec->desktop = d; + } + } + } + } + } if (!ec->desktop) { E_Exec_Instance *inst; @@ -2227,9 +2250,17 @@ _e_client_eval(E_Client *ec) } if (!ec->desktop) { + // special case hacks for specific apps that just don't do things + // right so we have to work around them + if (ec->icccm.class && ec->icccm.name && + (!strcmp(ec->icccm.class, "Steam")) && + (!strcmp(ec->icccm.name, "Steam"))) + { + ec->desktop = efreet_util_desktop_file_id_find("steam.desktop"); + } /* libreoffice and maybe others match window class with .desktop file name */ - if (ec->icccm.class) + else if (ec->icccm.class) { char buf[4096] = {0}; snprintf(buf, sizeof(buf), "%s.desktop", ec->icccm.class); diff --git a/src/bin/e_client.h b/src/bin/e_client.h index ceae23994..adb98fca1 100644 --- a/src/bin/e_client.h +++ b/src/bin/e_client.h @@ -568,6 +568,10 @@ struct E_Client unsigned char have_property E_BITFIELD; unsigned char vkbd E_BITFIELD; } vkbd; + + struct { + unsigned int steam_game_id; + } steam; struct { diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c index 0835ee912..21d139a7f 100644 --- a/src/bin/e_comp_x.c +++ b/src/bin/e_comp_x.c @@ -560,6 +560,8 @@ _e_comp_x_client_new_helper(E_Client *ec) ec->e.fetch.stack = 1; else if (atoms[i] == ATM_GTK_FRAME_EXTENTS) ec->comp_data->fetch_gtk_frame_extents = 1; + else if (atoms[i] == ATM_STEAM_GAME) + e_hints_window_steam_game_get(ec); else if (ec->re_manage) { if (atoms[i] == E_ATOM_DESKTOP_FILE) @@ -2200,6 +2202,12 @@ _e_comp_x_property(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_X_Event_W _e_comp_x_client_data_get(ec)->fetch_gtk_frame_extents = 1; EC_CHANGED(ec); } + else if (ev->atom == ATM_STEAM_GAME) + { + e_hints_window_steam_game_get(ec); + ec->changes.icon = 1; + EC_CHANGED(ec); + } return ECORE_CALLBACK_RENEW; } diff --git a/src/bin/e_hints.c b/src/bin/e_hints.c index f1b8f6125..eabf467a7 100644 --- a/src/bin/e_hints.c +++ b/src/bin/e_hints.c @@ -15,6 +15,8 @@ E_API Ecore_X_Atom ATM_ENLIGHTENMENT_SCALE = 0; E_API Ecore_X_Atom ATM_NETWM_SHOW_WINDOW_MENU = 0; E_API Ecore_X_Atom ATM_NETWM_PERFORM_BUTTON_ACTION = 0; E_API Ecore_X_Atom ATM_GTK_FRAME_EXTENTS = 0; + +E_API Ecore_X_Atom ATM_STEAM_GAME = 0; #endif EINTERN void @@ -34,6 +36,7 @@ e_hints_init(Ecore_Window root, Ecore_Window propwin) "_NET_WM_SHOW_WINDOW_MENU", "_NET_WM_PERFORM_BUTTON_ACTION", "_GTK_FRAME_EXTENTS", + "STEAM_GAME", }; Ecore_X_Atom atoms[EINA_C_ARRAY_LENGTH(atom_names)]; Ecore_X_Atom supported[46]; @@ -53,6 +56,7 @@ e_hints_init(Ecore_Window root, Ecore_Window propwin) ATM_NETWM_SHOW_WINDOW_MENU = atoms[6]; ATM_NETWM_PERFORM_BUTTON_ACTION = atoms[7]; ATM_GTK_FRAME_EXTENTS = atoms[8]; + ATM_STEAM_GAME = atoms[9]; supported_num = 0; /* Set what hints we support */ @@ -1605,6 +1609,22 @@ e_hints_window_qtopia_soft_menus_get(E_Client *ec) #endif } +E_API void +e_hints_window_steam_game_get(E_Client *ec) +{ +#ifdef HAVE_WAYLAND_ONLY + (void)ec; +#else + unsigned int val; + + if (!e_client_has_xwindow(ec)) return; + if (ecore_x_window_prop_card32_get(e_client_util_win_get(ec), ATM_STEAM_GAME, &val, 1)) + ec->steam.steam_game_id = val; + else + ec->steam.steam_game_id = 0; +#endif +} + E_API void e_hints_window_virtual_keyboard_state_get(E_Client *ec) { diff --git a/src/bin/e_hints.h b/src/bin/e_hints.h index 5fa1f3fc2..38854ae47 100644 --- a/src/bin/e_hints.h +++ b/src/bin/e_hints.h @@ -40,6 +40,8 @@ E_API void e_hints_window_e_state_get(E_Client *ec); E_API void e_hints_window_qtopia_soft_menu_get(E_Client *ec); E_API void e_hints_window_qtopia_soft_menus_get(E_Client *ec); +E_API void e_hints_window_steam_game_get(E_Client *ec); + E_API void e_hints_window_virtual_keyboard_state_get(E_Client *ec); E_API void e_hints_window_virtual_keyboard_get(E_Client *ec); @@ -58,6 +60,7 @@ extern E_API Ecore_X_Atom ATM_ENLIGHTENMENT_SCALE; extern E_API Ecore_X_Atom ATM_NETWM_SHOW_WINDOW_MENU; extern E_API Ecore_X_Atom ATM_NETWM_PERFORM_BUTTON_ACTION; extern E_API Ecore_X_Atom ATM_GTK_FRAME_EXTENTS; +extern E_API Ecore_X_Atom ATM_STEAM_GAME; #endif #ifdef HAVE_WAYLAND