mirror of
https://github.com/yuzu-emu/yuzu-android
synced 2025-08-06 07:52:32 -07:00
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:
@@ -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
|
||||
|
@@ -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
|
@@ -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) {
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user