mirror of
https://github.com/XorTroll/uLaunch
synced 2024-11-22 03:43:04 +00:00
Fix home button detection and crashes when switching menus
This commit is contained in:
parent
b20e374e12
commit
f477da1d24
6 changed files with 49 additions and 43 deletions
|
@ -4,6 +4,8 @@
|
|||
|
||||
namespace ipc {
|
||||
|
||||
// Note: domains and pointer buffer are required since ECS sessions will make use of them (like normal fs interfaces)
|
||||
|
||||
struct ServerOptions {
|
||||
static const size_t PointerBufferSize = 0x400;
|
||||
static const size_t MaxDomains = 0x40;
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include <util/util_Convert.hpp>
|
||||
#include <cfg/cfg_Config.hpp>
|
||||
|
||||
// Outside of anonymous namespace since these are accessed by IPC
|
||||
|
||||
ams::os::Mutex g_LastMenuMessageLock(false);
|
||||
dmi::MenuMessage g_LastMenuMessage = dmi::MenuMessage::Invalid;
|
||||
|
||||
|
@ -42,12 +44,12 @@ namespace {
|
|||
u8 *g_UsbViewerReadBuffer = nullptr;
|
||||
cfg::Config g_Config = {};
|
||||
ams::os::ThreadType g_UsbViewerThread;
|
||||
alignas(ams::os::ThreadStackAlignment) u8 g_UsbViewerThreadStack[0x8000];
|
||||
alignas(ams::os::ThreadStackAlignment) u8 g_UsbViewerThreadStack[0x4000];
|
||||
UsbMode g_UsbViewerMode = UsbMode::Invalid;
|
||||
|
||||
// In the USB packet, the first u32 / the first 4 bytes are the USB mode (raw RGBA or JPEG, depending on what the console supports)
|
||||
// In the USB packet, the first u32 stores the USB mode (raw RGBA or JPEG, depending on what the console supports)
|
||||
|
||||
constexpr size_t UsbPacketSize = RawRGBAScreenBufferSize + sizeof(u32);
|
||||
constexpr size_t UsbPacketSize = RawRGBAScreenBufferSize + sizeof(UsbMode);
|
||||
|
||||
}
|
||||
|
||||
|
@ -69,10 +71,13 @@ extern "C" {
|
|||
|
||||
u32 __nx_applet_type = AppletType_SystemApplet;
|
||||
u32 __nx_fs_num_sessions = 1;
|
||||
bool __nx_fsdev_support_cwd = false;
|
||||
u32 __nx_fsdev_direntry_cache_size = 0;
|
||||
|
||||
void __libnx_initheap();
|
||||
void __appInit();
|
||||
void __appExit();
|
||||
|
||||
}
|
||||
|
||||
extern char *fake_heap_start;
|
||||
|
@ -99,10 +104,9 @@ void __appInit() {
|
|||
}
|
||||
|
||||
void __appExit() {
|
||||
((void(*)())0xBEEFBABE)();
|
||||
// qlaunch should not terminate, so this is considered an invalid system state
|
||||
// am would fatal otherwise
|
||||
fatalThrow(0xDEBF);
|
||||
fatalThrow(0xDEADBABE);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -129,27 +133,25 @@ namespace {
|
|||
appletStartSleepSequence(true);
|
||||
}
|
||||
|
||||
Result LaunchMenu(dmi::MenuStartMode stmode, dmi::DaemonStatus status) {
|
||||
R_TRY(ecs::RegisterLaunchAsApplet(g_Config.menu_program_id, static_cast<u32>(stmode), "/ulaunch/bin/uMenu", &status, sizeof(status)));
|
||||
return ResultSuccess;
|
||||
inline Result LaunchMenu(dmi::MenuStartMode stmode, dmi::DaemonStatus status) {
|
||||
return ecs::RegisterLaunchAsApplet(g_Config.menu_program_id, static_cast<u32>(stmode), "/ulaunch/bin/uMenu", &status, sizeof(status));
|
||||
}
|
||||
|
||||
void HandleHomeButton() {
|
||||
if(am::LibraryAppletIsActive() && !am::LibraryAppletIsMenu()) {
|
||||
// An applet is opened (which is not our menu), thus close it and reopen the menu
|
||||
am::LibraryAppletTerminate();
|
||||
auto status = CreateStatus();
|
||||
UL_ASSERT(LaunchMenu(dmi::MenuStartMode::Menu, status));
|
||||
return;
|
||||
}
|
||||
if(am::ApplicationIsActive()) {
|
||||
if(am::ApplicationHasForeground()) {
|
||||
am::HomeMenuSetForeground();
|
||||
auto status = CreateStatus();
|
||||
UL_ASSERT(LaunchMenu(dmi::MenuStartMode::MenuApplicationSuspended, status));
|
||||
return;
|
||||
}
|
||||
else if(am::ApplicationIsActive() && am::ApplicationHasForeground()) {
|
||||
// Hide the application currently on focus and open our menu
|
||||
am::HomeMenuSetForeground();
|
||||
auto status = CreateStatus();
|
||||
UL_ASSERT(LaunchMenu(dmi::MenuStartMode::MenuApplicationSuspended, status));
|
||||
}
|
||||
if(am::LibraryAppletIsMenu()) {
|
||||
else if(am::LibraryAppletIsMenu()) {
|
||||
// Send a message to our menu to handle itself the home press
|
||||
std::scoped_lock lk(g_LastMenuMessageLock);
|
||||
g_LastMenuMessage = dmi::MenuMessage::HomeRequest;
|
||||
}
|
||||
|
|
|
@ -8,21 +8,20 @@ extern dmi::MenuMessage g_LastMenuMessage;
|
|||
namespace ipc {
|
||||
|
||||
ams::Result PrivateService::Initialize(const ams::sf::ClientProcessId &client_pid) {
|
||||
if(this->initialized) {
|
||||
return ams::ResultSuccess();
|
||||
}
|
||||
|
||||
u64 program_id = 0;
|
||||
R_TRY(pminfoGetProgramId(&program_id, client_pid.process_id.value));
|
||||
|
||||
auto last_menu_program_id = am::LibraryAppletGetProgramIdForAppletId(am::LibraryAppletGetMenuAppletId());
|
||||
// If Menu hasn't been launched it's program ID will be 0/invalid, thus a != check wouldn't be enough
|
||||
// If any of the IDs is invalid, something unexpected is happening...
|
||||
if((last_menu_program_id == 0) || (program_id == 0) || (program_id != last_menu_program_id)) {
|
||||
return RES_VALUE(Daemon, PrivateServiceInvalidProcess);
|
||||
if(!this->initialized) {
|
||||
u64 program_id = 0;
|
||||
R_TRY(pminfoGetProgramId(&program_id, client_pid.process_id.value));
|
||||
|
||||
auto last_menu_program_id = am::LibraryAppletGetProgramIdForAppletId(am::LibraryAppletGetMenuAppletId());
|
||||
// If Menu hasn't been launched it's program ID will be 0/invalid, thus a != check wouldn't be enough
|
||||
// If any of the IDs is invalid, something unexpected is happening...
|
||||
if((last_menu_program_id == 0) || (program_id == 0) || (program_id != last_menu_program_id)) {
|
||||
return RES_VALUE(Daemon, PrivateServiceInvalidProcess);
|
||||
}
|
||||
|
||||
this->initialized = true;
|
||||
}
|
||||
|
||||
this->initialized = true;
|
||||
return ams::ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -33,6 +32,12 @@ namespace ipc {
|
|||
|
||||
std::scoped_lock lk(g_LastMenuMessageLock);
|
||||
out_msg.SetValue(g_LastMenuMessage);
|
||||
auto f = fopen("sdmc:/udaemon-priv.log", "ab+");
|
||||
if(f) {
|
||||
auto msg = "Sending message: " + std::to_string(static_cast<u32>(g_LastMenuMessage));
|
||||
fwrite(msg.c_str(), msg.length(), 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
g_LastMenuMessage = dmi::MenuMessage::Invalid;
|
||||
return ams::ResultSuccess();
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace {
|
||||
|
||||
Service g_DaemonPrivateService;
|
||||
|
||||
Result daemonPrivateInitialize(Service *srv) {
|
||||
u64 pid_placeholder = 0;
|
||||
return serviceDispatchIn(srv, 0, pid_placeholder,
|
||||
|
@ -12,9 +10,11 @@ namespace {
|
|||
}
|
||||
|
||||
Result daemonPrivateGetMessage(Service *srv, dmi::MenuMessage *out_msg) {
|
||||
return serviceDispatchOut(&g_DaemonPrivateService, 1, out_msg);
|
||||
return serviceDispatchOut(srv, 1, *out_msg);
|
||||
}
|
||||
|
||||
Service g_DaemonPrivateService;
|
||||
|
||||
Result daemonInitializePrivateService() {
|
||||
if(serviceIsActive(&g_DaemonPrivateService)) {
|
||||
return ResultSuccess;
|
||||
|
@ -58,11 +58,10 @@ namespace am {
|
|||
break;
|
||||
}
|
||||
|
||||
auto tmp_msg = daemonGetMessage();
|
||||
|
||||
auto last_msg = daemonGetMessage();
|
||||
mutexLock(&g_ReceiverLock);
|
||||
for(auto &[cb, msg] : g_ReceiverCallbackTable) {
|
||||
if(msg == tmp_msg) {
|
||||
if(msg == last_msg) {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +80,7 @@ namespace am {
|
|||
R_TRY(daemonInitializePrivateService());
|
||||
|
||||
g_ReceiveThreadShouldStop = false;
|
||||
R_TRY(threadCreate(&g_ReceiverThread, &DaemonMessageReceiverThread, nullptr, nullptr, 0x1000, 0x2b, -2));
|
||||
R_TRY(threadCreate(&g_ReceiverThread, &DaemonMessageReceiverThread, nullptr, nullptr, 0x2000, 0x2B, -2));
|
||||
R_TRY(threadStart(&g_ReceiverThread));
|
||||
|
||||
g_Initialized = true;
|
||||
|
|
|
@ -679,6 +679,8 @@ namespace ui {
|
|||
}
|
||||
|
||||
void MenuLayout::MoveFolder(const std::string &name, bool fade) {
|
||||
this->itemsMenu->SetSelectedItem(0);
|
||||
|
||||
if(fade) {
|
||||
g_MenuApplication->FadeOut();
|
||||
}
|
||||
|
|
|
@ -14,12 +14,8 @@
|
|||
"filesystem_access": {
|
||||
"permissions": "0xFFFFFFFFFFFFFFFF"
|
||||
},
|
||||
"service_host": [
|
||||
"*"
|
||||
],
|
||||
"service_access": [
|
||||
"*"
|
||||
],
|
||||
"service_host": [ "*" ],
|
||||
"service_access": [ "*" ],
|
||||
"kernel_capabilities": [
|
||||
{
|
||||
"type": "kernel_flags",
|
||||
|
|
Loading…
Reference in a new issue