diff --git a/src/app/application_services.cpp b/src/app/application_services.cpp index ef940cf5e8..7ae97bd391 100644 --- a/src/app/application_services.cpp +++ b/src/app/application_services.cpp @@ -689,7 +689,7 @@ void Application::initStyleThemeAndWayland() { throw std::runtime_error("failed to connect to Wayland display"); } m_compositorPlatform.initialize(); - m_screenTimeService.initialize(&m_wayland); + m_screenTimeService.initialize(&m_compositorPlatform); syncScreenTimeService(); m_screenTimeService.setChangeCallback([this]() { if (m_panelManager.isOpenPanel("control-center") && m_panelManager.isActivePanelContext("screen-time")) { diff --git a/src/compositors/compositor_platform.cpp b/src/compositors/compositor_platform.cpp index dd73c99b40..556607d3df 100644 --- a/src/compositors/compositor_platform.cpp +++ b/src/compositors/compositor_platform.cpp @@ -29,6 +29,7 @@ #include "compositors/workspace_alert_service.h" #include "core/log.h" #include "core/process/process.h" +#include "util/string_utils.h" #include "wayland/output_probe.h" #include "wayland/wayland_connection.h" #include "wayland/wayland_workspaces.h" @@ -854,7 +855,26 @@ std::optional CompositorPlatform::activeToplevel() const { return m_wayland.activeToplevel(); } -wl_output* CompositorPlatform::activeToplevelOutput() const { return m_wayland.activeToplevelOutput(); } +wl_output* CompositorPlatform::activeToplevelOutput() const { + if (compositors::isKde() && m_kwinActiveWindow != nullptr) { + if (const auto focusedName = m_kwinActiveWindow->focusedOutputName(); focusedName.has_value()) { + if (wl_output* output = resolveOutputName(*focusedName); output != nullptr) { + return output; + } + } + } + if (compositors::detect() == compositors::CompositorKind::Mango && m_workspaces != nullptr) { + if (wl_output* selected = m_workspaces->mangoIpcSelectedOutput(); selected != nullptr) { + return selected; + } + } + if (compositors::detect() == compositors::CompositorKind::Dwl && m_workspaces != nullptr) { + if (wl_output* selected = m_workspaces->dwlIpcSelectedOutput(); selected != nullptr) { + return selected; + } + } + return m_wayland.activeToplevelOutput(); +} std::vector CompositorPlatform::runningAppIds(wl_output* outputFilter) const { if (compositors::isKde() && m_kwinActiveWindow != nullptr && m_kwinActiveWindow->isAvailable()) { @@ -953,6 +973,18 @@ void CompositorPlatform::activateToplevel(zwlr_foreign_toplevel_handle_v1* handl m_wayland.activateToplevel(handle); } +void CompositorPlatform::activateToplevelForAppId(std::string_view appId) { + if (appId.empty()) { + return; + } + const std::string idLower = StringUtils::toLower(std::string(appId)); + const auto windows = windowsForApp(idLower, idLower); + if (windows.empty()) { + return; + } + activateToplevelInfo(windows.back()); +} + void CompositorPlatform::activateToplevelInfo(const ToplevelInfo& window) { if (window.exactIdentity && !window.identifier.empty() diff --git a/src/compositors/compositor_platform.h b/src/compositors/compositor_platform.h index 96fb91baed..fe7256185f 100644 --- a/src/compositors/compositor_platform.h +++ b/src/compositors/compositor_platform.h @@ -112,6 +112,7 @@ class CompositorPlatform { [[nodiscard]] bool hasExactWindowIdentity() const noexcept; [[nodiscard]] bool containsWlrToplevelHandle(zwlr_foreign_toplevel_handle_v1* handle) const; void activateToplevel(zwlr_foreign_toplevel_handle_v1* handle); + void activateToplevelForAppId(std::string_view appId); void activateToplevelInfo(const ToplevelInfo& window); void closeToplevel(zwlr_foreign_toplevel_handle_v1* handle); void closeToplevelInfo(const ToplevelInfo& window); diff --git a/src/shell/settings/settings_window.cpp b/src/shell/settings/settings_window.cpp index e630311418..fe0b5951dd 100644 --- a/src/shell/settings/settings_window.cpp +++ b/src/shell/settings/settings_window.cpp @@ -1,5 +1,6 @@ #include "shell/settings/settings_window.h" +#include "compositors/compositor_platform.h" #include "config/config_service.h" #include "config/config_types.h" #include "core/deferred_call.h" @@ -95,10 +96,10 @@ namespace { return {"bar", barName, std::string(lane)}; } - void focusExistingSettingsWindow(WaylandConnection& wayland, wl_surface* surface) { + void focusExistingSettingsWindow(CompositorPlatform& platform, WaylandConnection& wayland, wl_surface* surface) { static constexpr std::string_view kSettingsAppId = "dev.noctalia.Noctalia"; wayland.activateSurface(surface); - wayland.activateToplevelForAppId(kSettingsAppId); + platform.activateToplevelForAppId(kSettingsAppId); } [[nodiscard]] bool isSettingsSearchTypingKey(const KeyboardEvent& event) { @@ -400,8 +401,8 @@ void SettingsWindow::open(std::string context) { if (isOpen()) { const auto refocus = [this]() { - if (m_wayland != nullptr && m_surface != nullptr) { - focusExistingSettingsWindow(*m_wayland, m_surface->wlSurface()); + if (m_platform != nullptr && m_wayland != nullptr && m_surface != nullptr) { + focusExistingSettingsWindow(*m_platform, *m_wayland, m_surface->wlSurface()); } }; refocus(); diff --git a/src/system/brightness_service.cpp b/src/system/brightness_service.cpp index 027ad1d21c..cb6055ac14 100644 --- a/src/system/brightness_service.cpp +++ b/src/system/brightness_service.cpp @@ -1553,7 +1553,7 @@ void BrightnessService::registerIpc(IpcService& ipc, std::function onBat output = context->output; } if (output == nullptr) { - output = m_impl->wayland.activeToplevelOutput(); + output = m_impl->platform.activeToplevelOutput(); } if (output == nullptr) { output = m_impl->platform.preferredInteractiveOutput(); diff --git a/src/system/screen_time_service.cpp b/src/system/screen_time_service.cpp index e9cef88fa8..2d421effac 100644 --- a/src/system/screen_time_service.cpp +++ b/src/system/screen_time_service.cpp @@ -1,5 +1,6 @@ #include "system/screen_time_service.h" +#include "compositors/compositor_platform.h" #include "core/log.h" #include "system/app_identity.h" #include "system/desktop_entry.h" @@ -7,7 +8,6 @@ #include "time/time_format.h" #include "util/file_utils.h" #include "util/string_utils.h" -#include "wayland/wayland_connection.h" #include "wayland/wayland_toplevels.h" #include @@ -281,8 +281,8 @@ ScreenTimeService::DayRecord ScreenTimeService::materializeDayForCharts(const Da return day; } -void ScreenTimeService::initialize(WaylandConnection* wayland) { - m_wayland = wayland; +void ScreenTimeService::initialize(CompositorPlatform* platform) { + m_platform = platform; const std::string dir = FileUtils::stateDir(); m_storagePath = dir.empty() ? "screen_time.json" : dir + "/screen_time.json"; load(); @@ -884,10 +884,10 @@ void ScreenTimeService::pruneOldDaysLocked() { } std::string ScreenTimeService::appKeyForActive() const { - if (m_wayland == nullptr) { + if (m_platform == nullptr) { return {}; } - const auto active = m_wayland->activeToplevel(); + const auto active = m_platform->activeToplevel(); if (!active.has_value()) { return {}; } diff --git a/src/system/screen_time_service.h b/src/system/screen_time_service.h index c38c3726a7..c5e7ed8e83 100644 --- a/src/system/screen_time_service.h +++ b/src/system/screen_time_service.h @@ -11,7 +11,7 @@ #include #include -class WaylandConnection; +class CompositorPlatform; struct ScreenTimeAppUsage { std::string appKey; @@ -42,7 +42,7 @@ struct ScreenTimeSnapshot { class ScreenTimeService { public: - void initialize(WaylandConnection* wayland); + void initialize(CompositorPlatform* platform); void shutdown(); void onFocusChange(); @@ -88,7 +88,7 @@ class ScreenTimeService { std::chrono::seconds amount, const DayRecord& profile, std::vector& buckets ); - WaylandConnection* m_wayland = nullptr; + CompositorPlatform* m_platform = nullptr; std::function m_changeCallback; Timer m_tickTimer; std::string m_storagePath;