Improved shortcut: add games in applist for Windows, question for start game at fullscreen & better unicode support for some Windows path funcs.

This commit is contained in:
boludoz
2023-10-15 02:02:22 -03:00
parent 1a4abd184f
commit 3062a35eb1
9 changed files with 522 additions and 222 deletions

View File

@@ -36,4 +36,63 @@ std::string PathToUTF8String(const std::filesystem::path& path) {
return ToUTF8String(path.u8string());
}
std::u8string U8FilenameSantizer(const std::u8string_view u8filename) {
std::u8string u8path_santized{u8filename.begin(), u8filename.end()};
size_t eSizeSanitized = u8path_santized.size();
// Special case for ":", for example: 'Pepe: La secuela' --> 'Pepe - La
// secuela' or 'Pepe : La secuela' --> 'Pepe - La secuela'
for (size_t i = 0; i < eSizeSanitized; i++) {
switch (u8path_santized[i]) {
case u8':':
if (i == 0 || i == eSizeSanitized - 1) {
u8path_santized.replace(i, 1, u8"_");
} else if (u8path_santized[i - 1] == u8' ') {
u8path_santized.replace(i, 1, u8"-");
} else {
u8path_santized.replace(i, 1, u8" -");
eSizeSanitized++;
}
break;
case u8'\\':
case u8'/':
case u8'*':
case u8'?':
case u8'\"':
case u8'<':
case u8'>':
case u8'|':
case u8'\0':
u8path_santized.replace(i, 1, u8"_");
break;
default:
break;
}
}
// Delete duplicated spaces || Delete duplicated dots (MacOS i think)
for (size_t i = 0; i < eSizeSanitized - 1; i++) {
if ((u8path_santized[i] == u8' ' && u8path_santized[i + 1] == u8' ') ||
(u8path_santized[i] == u8'.' && u8path_santized[i + 1] == u8'.')) {
u8path_santized.erase(i, 1);
i--;
}
}
// Delete all spaces and dots at the end (Windows almost)
while (u8path_santized.back() == u8' ' || u8path_santized.back() == u8'.') {
u8path_santized.pop_back();
}
if (u8path_santized.empty()) {
return u8"";
}
return u8path_santized;
}
std::string UTF8FilenameSantizer(const std::string_view filename) {
return ToUTF8String(U8FilenameSantizer(ToU8String(filename)));
}
} // namespace Common::FS

View File

@@ -82,4 +82,24 @@ concept IsChar = std::same_as<T, char>;
*/
[[nodiscard]] std::string PathToUTF8String(const std::filesystem::path& path);
} // namespace Common::FS
/**
* Fix filename (remove invalid characters)
*
* @param u8_string dirty encoded filename string
*
* @returns utf8_string santized filename string
*
*/
[[nodiscard]] std::u8string U8FilenameSantizer(const std::u8string_view u8filename);
/**
* Fix filename (remove invalid characters)
*
* @param utf8_string dirty encoded filename string
*
* @returns utf8_string santized filename string
*
*/
[[nodiscard]] std::string UTF8FilenameSantizer(const std::string_view filename);
} // namespace Common::FS

View File

@@ -6,6 +6,7 @@
#include <unordered_map>
#include "common/fs/fs.h"
#include "common/string_util.h"
#ifdef ANDROID
#include "common/fs/fs_android.h"
#endif
@@ -14,7 +15,7 @@
#include "common/logging/log.h"
#ifdef _WIN32
#include <shlobj.h> // Used in GetExeDirectory()
#include <shlobj.h> // Used in GetExeDirectory() and GetWindowsDesktop()
#else
#include <cstdlib> // Used in Get(Home/Data)Directory()
#include <pwd.h> // Used in GetHomeDirectory()
@@ -250,30 +251,39 @@ void SetYuzuPath(YuzuPath yuzu_path, const fs::path& new_path) {
#ifdef _WIN32
fs::path GetExeDirectory() {
wchar_t exe_path[MAX_PATH];
WCHAR exe_path[MAX_PATH];
if (GetModuleFileNameW(nullptr, exe_path, MAX_PATH) == 0) {
if (SUCCEEDED(GetModuleFileNameW(nullptr, exe_path, MAX_PATH))) {
std::wstring wideExePath(exe_path);
// UTF-16 filesystem lib to UTF-8 is broken, so we need to convert to UTF-8 with the with
// the Windows library (Filesystem converts the strings literally).
return fs::path{Common::UTF16ToUTF8(wideExePath)}.parent_path();
} else {
LOG_ERROR(Common_Filesystem,
"Failed to get the path to the executable of the current process");
"[GetExeDirectory] Failed to get the path to the executable of the current "
"process");
}
return fs::path{exe_path}.parent_path();
return fs::path{};
}
fs::path GetAppDataRoamingDirectory() {
PWSTR appdata_roaming_path = nullptr;
SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, nullptr, &appdata_roaming_path);
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &appdata_roaming_path))) {
std::wstring wideAppdataRoamingPath(appdata_roaming_path);
CoTaskMemFree(appdata_roaming_path);
auto fs_appdata_roaming_path = fs::path{appdata_roaming_path};
CoTaskMemFree(appdata_roaming_path);
if (fs_appdata_roaming_path.empty()) {
LOG_ERROR(Common_Filesystem, "Failed to get the path to the %APPDATA% directory");
// UTF-16 filesystem lib to UTF-8 is broken, so we need to convert to UTF-8 with the with
// the Windows library (Filesystem converts the strings literally).
return fs::path{Common::UTF16ToUTF8(wideAppdataRoamingPath)};
} else {
LOG_ERROR(Common_Filesystem,
"[GetAppDataRoamingDirectory] Failed to get the path to the %APPDATA% directory");
}
return fs_appdata_roaming_path;
return fs::path{};
}
#else
@@ -338,6 +348,57 @@ fs::path GetBundleDirectory() {
#endif
fs::path GetDesktopPath() {
#if defined(_WIN32)
PWSTR DesktopPath = nullptr;
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Desktop, 0, NULL, &DesktopPath))) {
std::wstring wideDesktopPath(DesktopPath);
CoTaskMemFree(DesktopPath);
// UTF-16 filesystem lib to UTF-8 is broken, so we need to convert to UTF-8 with the with
// the Windows library (Filesystem converts the strings literally).
return fs::path{Common::UTF16ToUTF8(wideDesktopPath)};
} else {
LOG_ERROR(Common_Filesystem,
"[GetDesktopPath] Failed to get the path to the desktop directory");
}
#else
fs::path shortcut_path = GetHomeDirectory() / "Desktop";
if (fs::exists(shortcut_path)) {
return shortcut_path;
}
#endif
return fs::path{};
}
fs::path GetAppsShortcutsPath() {
#if defined(_WIN32)
PWSTR AppShortcutsPath = nullptr;
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_CommonPrograms, 0, NULL, &AppShortcutsPath))) {
std::wstring wideAppShortcutsPath(AppShortcutsPath);
CoTaskMemFree(AppShortcutsPath);
// UTF-16 filesystem lib to UTF-8 is broken, so we need to convert to UTF-8 with the with
// the Windows library (Filesystem converts the strings literally).
return fs::path{Common::UTF16ToUTF8(wideAppShortcutsPath)};
} else {
LOG_ERROR(Common_Filesystem,
"[GetAppsShortcutsPath] Failed to get the path to the App Shortcuts directory");
}
#else
fs::path shortcut_path = GetHomeDirectory() / ".local/share/applications";
if (!fs::exists(shortcut_path)) {
shortcut_path = std::filesystem::path("/usr/share/applications");
return shortcut_path;
} else {
return shortcut_path;
}
#endif
return fs::path{};
}
// vvvvvvvvvv Deprecated vvvvvvvvvv //
std::string_view RemoveTrailingSlash(std::string_view path) {

View File

@@ -244,7 +244,6 @@ void SetYuzuPath(YuzuPath yuzu_path, const Path& new_path) {
* @returns The path of the current user's %APPDATA% directory.
*/
[[nodiscard]] std::filesystem::path GetAppDataRoamingDirectory();
#else
/**
@@ -275,6 +274,20 @@ void SetYuzuPath(YuzuPath yuzu_path, const Path& new_path) {
#endif
/**
* Gets the path of the current user's desktop directory.
*
* @returns The path of the current user's desktop directory.
*/
[[nodiscard]] std::filesystem::path GetDesktopPath();
/**
* Gets the path of the current user's apps directory.
*
* @returns The path of the current user's apps directory.
*/
[[nodiscard]] std::filesystem::path GetAppsShortcutsPath();
// vvvvvvvvvv Deprecated vvvvvvvvvv //
// Removes the final '/' or '\' if one exists