Procházet zdrojové kódy

applets: Send focus state change message on applet state change

Fixes the softlock after the controller applet exits in Mario Kart 8 Deluxe.
Morph před 5 roky
rodič
revize
51ca93981d

+ 8 - 4
src/core/hle/service/am/am.cpp

@@ -619,16 +619,20 @@ std::size_t AppletMessageQueue::GetMessageCount() const {
     return messages.size();
 }
 
+void AppletMessageQueue::RequestExit() {
+    PushMessage(AppletMessage::ExitRequested);
+}
+
+void AppletMessageQueue::FocusStateChanged() {
+    PushMessage(AppletMessage::FocusStateChanged);
+}
+
 void AppletMessageQueue::OperationModeChanged() {
     PushMessage(AppletMessage::OperationModeChanged);
     PushMessage(AppletMessage::PerformanceModeChanged);
     on_operation_mode_changed->GetWritableEvent()->Signal();
 }
 
-void AppletMessageQueue::RequestExit() {
-    PushMessage(AppletMessage::ExitRequested);
-}
-
 ICommonStateGetter::ICommonStateGetter(Core::System& system_,
                                        std::shared_ptr<AppletMessageQueue> msg_queue_)
     : ServiceFramework{system_, "ICommonStateGetter"}, msg_queue{std::move(msg_queue_)} {

+ 2 - 1
src/core/hle/service/am/am.h

@@ -61,8 +61,9 @@ public:
     void PushMessage(AppletMessage msg);
     AppletMessage PopMessage();
     std::size_t GetMessageCount() const;
-    void OperationModeChanged();
     void RequestExit();
+    void FocusStateChanged();
+    void OperationModeChanged();
 
 private:
     std::queue<AppletMessage> messages;

+ 33 - 7
src/core/hle/service/am/applets/applets.cpp

@@ -17,6 +17,8 @@
 #include "core/hle/kernel/k_writable_event.h"
 #include "core/hle/kernel/server_session.h"
 #include "core/hle/service/am/am.h"
+#include "core/hle/service/am/applet_ae.h"
+#include "core/hle/service/am/applet_oe.h"
 #include "core/hle/service/am/applets/applets.h"
 #include "core/hle/service/am/applets/controller.h"
 #include "core/hle/service/am/applets/error.h"
@@ -24,17 +26,20 @@
 #include "core/hle/service/am/applets/profile_select.h"
 #include "core/hle/service/am/applets/software_keyboard.h"
 #include "core/hle/service/am/applets/web_browser.h"
+#include "core/hle/service/sm/sm.h"
 
 namespace Service::AM::Applets {
 
-AppletDataBroker::AppletDataBroker(Kernel::KernelCore& kernel) {
+AppletDataBroker::AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_)
+    : system{system_}, applet_mode{applet_mode_} {
     state_changed_event =
-        Kernel::KEvent::Create(kernel, "ILibraryAppletAccessor:StateChangedEvent");
+        Kernel::KEvent::Create(system.Kernel(), "ILibraryAppletAccessor:StateChangedEvent");
     state_changed_event->Initialize();
-    pop_out_data_event = Kernel::KEvent::Create(kernel, "ILibraryAppletAccessor:PopDataOutEvent");
+    pop_out_data_event =
+        Kernel::KEvent::Create(system.Kernel(), "ILibraryAppletAccessor:PopDataOutEvent");
     pop_out_data_event->Initialize();
-    pop_interactive_out_data_event =
-        Kernel::KEvent::Create(kernel, "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
+    pop_interactive_out_data_event = Kernel::KEvent::Create(
+        system.Kernel(), "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
     pop_interactive_out_data_event->Initialize();
 }
 
@@ -114,6 +119,27 @@ void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&&
 
 void AppletDataBroker::SignalStateChanged() const {
     state_changed_event->GetWritableEvent()->Signal();
+
+    switch (applet_mode) {
+    case LibraryAppletMode::AllForeground:
+    case LibraryAppletMode::AllForegroundInitiallyHidden: {
+        auto applet_oe = system.ServiceManager().GetService<AppletOE>("appletOE");
+        auto applet_ae = system.ServiceManager().GetService<AppletAE>("appletAE");
+
+        if (applet_oe) {
+            applet_oe->GetMessageQueue()->FocusStateChanged();
+            break;
+        }
+
+        if (applet_ae) {
+            applet_ae->GetMessageQueue()->FocusStateChanged();
+            break;
+        }
+        break;
+    }
+    default:
+        break;
+    }
 }
 
 std::shared_ptr<Kernel::KReadableEvent> AppletDataBroker::GetNormalDataEvent() const {
@@ -128,8 +154,8 @@ std::shared_ptr<Kernel::KReadableEvent> AppletDataBroker::GetStateChangedEvent()
     return state_changed_event->GetReadableEvent();
 }
 
-Applet::Applet(Kernel::KernelCore& kernel_, LibraryAppletMode applet_mode_)
-    : broker{kernel_}, applet_mode{applet_mode_} {}
+Applet::Applet(Core::System& system_, LibraryAppletMode applet_mode_)
+    : broker{system_, applet_mode_}, applet_mode{applet_mode_} {}
 
 Applet::~Applet() = default;
 

+ 5 - 2
src/core/hle/service/am/applets/applets.h

@@ -72,7 +72,7 @@ enum class LibraryAppletMode : u32 {
 
 class AppletDataBroker final {
 public:
-    explicit AppletDataBroker(Kernel::KernelCore& kernel_);
+    explicit AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_);
     ~AppletDataBroker();
 
     struct RawChannelData {
@@ -102,6 +102,9 @@ public:
     std::shared_ptr<Kernel::KReadableEvent> GetStateChangedEvent() const;
 
 private:
+    Core::System& system;
+    LibraryAppletMode applet_mode;
+
     // Queues are named from applet's perspective
 
     // PopNormalDataToApplet and PushNormalDataFromGame
@@ -127,7 +130,7 @@ private:
 
 class Applet {
 public:
-    explicit Applet(Kernel::KernelCore& kernel_, LibraryAppletMode applet_mode_);
+    explicit Applet(Core::System& system_, LibraryAppletMode applet_mode_);
     virtual ~Applet();
 
     virtual void Initialize();

+ 1 - 1
src/core/hle/service/am/applets/controller.cpp

@@ -47,7 +47,7 @@ static Core::Frontend::ControllerParameters ConvertToFrontendParameters(
 
 Controller::Controller(Core::System& system_, LibraryAppletMode applet_mode_,
                        const Core::Frontend::ControllerApplet& frontend_)
-    : Applet{system_.Kernel(), applet_mode_}, frontend{frontend_}, system{system_} {}
+    : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
 
 Controller::~Controller() = default;
 

+ 1 - 1
src/core/hle/service/am/applets/error.cpp

@@ -88,7 +88,7 @@ ResultCode Decode64BitError(u64 error) {
 
 Error::Error(Core::System& system_, LibraryAppletMode applet_mode_,
              const Core::Frontend::ErrorApplet& frontend_)
-    : Applet{system_.Kernel(), applet_mode_}, frontend{frontend_}, system{system_} {}
+    : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
 
 Error::~Error() = default;
 

+ 3 - 3
src/core/hle/service/am/applets/general_backend.cpp

@@ -39,7 +39,7 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix)
 
 Auth::Auth(Core::System& system_, LibraryAppletMode applet_mode_,
            Core::Frontend::ParentalControlsApplet& frontend_)
-    : Applet{system_.Kernel(), applet_mode_}, frontend{frontend_}, system{system_} {}
+    : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
 
 Auth::~Auth() = default;
 
@@ -155,7 +155,7 @@ void Auth::AuthFinished(bool is_successful) {
 
 PhotoViewer::PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_,
                          const Core::Frontend::PhotoViewerApplet& frontend_)
-    : Applet{system_.Kernel(), applet_mode_}, frontend{frontend_}, system{system_} {}
+    : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
 
 PhotoViewer::~PhotoViewer() = default;
 
@@ -205,7 +205,7 @@ void PhotoViewer::ViewFinished() {
 }
 
 StubApplet::StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_)
-    : Applet{system_.Kernel(), applet_mode_}, id{id_}, system{system_} {}
+    : Applet{system_, applet_mode_}, id{id_}, system{system_} {}
 
 StubApplet::~StubApplet() = default;
 

+ 1 - 1
src/core/hle/service/am/applets/profile_select.cpp

@@ -17,7 +17,7 @@ constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1};
 
 ProfileSelect::ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_,
                              const Core::Frontend::ProfileSelectApplet& frontend_)
-    : Applet{system_.Kernel(), applet_mode_}, frontend{frontend_}, system{system_} {}
+    : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
 
 ProfileSelect::~ProfileSelect() = default;
 

+ 1 - 1
src/core/hle/service/am/applets/software_keyboard.cpp

@@ -44,7 +44,7 @@ void SetReplyBase(std::vector<u8>& reply, SwkbdState state, SwkbdReplyType reply
 
 SoftwareKeyboard::SoftwareKeyboard(Core::System& system_, LibraryAppletMode applet_mode_,
                                    Core::Frontend::SoftwareKeyboardApplet& frontend_)
-    : Applet{system_.Kernel(), applet_mode_}, frontend{frontend_}, system{system_} {}
+    : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
 
 SoftwareKeyboard::~SoftwareKeyboard() = default;
 

+ 1 - 1
src/core/hle/service/am/applets/web_browser.cpp

@@ -210,7 +210,7 @@ void ExtractSharedFonts(Core::System& system) {
 
 WebBrowser::WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_,
                        const Core::Frontend::WebBrowserApplet& frontend_)
-    : Applet{system_.Kernel(), applet_mode_}, frontend(frontend_), system{system_} {}
+    : Applet{system_, applet_mode_}, frontend(frontend_), system{system_} {}
 
 WebBrowser::~WebBrowser() = default;