From 629397f222d0a225d0fdd757c6b01545b0c5967c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Thu, 2 May 2019 02:45:48 +0200 Subject: [PATCH] Add basic support for loading ControlLook add-ons app_server just passes the add-on path around. Maybe we should make sure the add-on can be loaded when setting it. Change-Id: I3acd3299782a22c1666bd5435dbf3d8053e359fa Reviewed-on: https://review.haiku-os.org/c/1430 Reviewed-by: waddlesplash --- headers/os/interface/ControlLook.h | 2 + headers/private/app/ServerProtocol.h | 2 + headers/private/interface/InterfacePrivate.h | 3 + src/kits/interface/ControlLook.cpp | 4 +- src/kits/interface/InterfaceDefs.cpp | 69 +++++++++++++++++++- src/servers/app/DesktopSettings.cpp | 36 ++++++++++ src/servers/app/DesktopSettings.h | 4 ++ src/servers/app/DesktopSettingsPrivate.h | 4 ++ src/servers/app/ServerApp.cpp | 33 ++++++++++ 9 files changed, 152 insertions(+), 5 deletions(-) diff --git a/headers/os/interface/ControlLook.h b/headers/os/interface/ControlLook.h index ad9348241f..72746a5cf0 100644 --- a/headers/os/interface/ControlLook.h +++ b/headers/os/interface/ControlLook.h @@ -418,6 +418,8 @@ protected: extern BControlLook* be_control_look; +extern "C" _EXPORT BControlLook *instantiate_control_look(image_id id); + } // namespace BPrivate diff --git a/headers/private/app/ServerProtocol.h b/headers/private/app/ServerProtocol.h index c564eb6bb3..a6795e6ba3 100644 --- a/headers/private/app/ServerProtocol.h +++ b/headers/private/app/ServerProtocol.h @@ -189,6 +189,8 @@ enum { AS_R5_SET_DECORATOR, AS_COUNT_DECORATORS, AS_GET_DECORATOR_NAME, + AS_SET_CONTROL_LOOK, + AS_GET_CONTROL_LOOK, AS_COUNT_WORKSPACES, AS_CURRENT_WORKSPACE, diff --git a/headers/private/interface/InterfacePrivate.h b/headers/private/interface/InterfacePrivate.h index fead585903..bdff9c23bc 100644 --- a/headers/private/interface/InterfacePrivate.h +++ b/headers/private/interface/InterfacePrivate.h @@ -26,6 +26,9 @@ int32 get_bytes_per_row(color_space colorSpace, int32 width); void get_workspaces_layout(uint32* _columns, uint32* _rows); void set_workspaces_layout(uint32 columns, uint32 rows); +bool get_control_look(BString& path); +status_t set_control_look(const BString& path); + } // namespace BPrivate diff --git a/src/kits/interface/ControlLook.cpp b/src/kits/interface/ControlLook.cpp index aab2e91958..7d410a7f4a 100644 --- a/src/kits/interface/ControlLook.cpp +++ b/src/kits/interface/ControlLook.cpp @@ -89,9 +89,7 @@ void BControlLook::_ReservedControlLook9() {} void BControlLook::_ReservedControlLook10() {} -// NOTE: May come from a add-on in the future. Initialized in -// InterfaceDefs.cpp +// Initialized in InterfaceDefs.cpp BControlLook* be_control_look = NULL; - } // namespace BPrivate diff --git a/src/kits/interface/InterfaceDefs.cpp b/src/kits/interface/InterfaceDefs.cpp index ec9fce2481..1e5c38c1bc 100644 --- a/src/kits/interface/InterfaceDefs.cpp +++ b/src/kits/interface/InterfaceDefs.cpp @@ -162,6 +162,8 @@ static const char* kColorNames[kColorWhichCount] = { NULL }; +static image_id sControlLookAddon = -1; + namespace BPrivate { @@ -1286,8 +1288,24 @@ _init_interface_kit_() if (be_clipboard == NULL) be_clipboard = new BClipboard(NULL); - // TODO: Could support different themes here in the future. - be_control_look = new HaikuControlLook(); + BString path; + if (get_control_look(path) && path.Length() > 0) { + BControlLook* (*instantiate)(image_id); + + sControlLookAddon = load_add_on(path.String()); + if (sControlLookAddon >= 0 + && get_image_symbol(sControlLookAddon, + "instantiate_control_look", + B_SYMBOL_TYPE_TEXT, (void **)&instantiate) == B_OK) { + be_control_look = instantiate(sControlLookAddon); + if (be_control_look == NULL) { + unload_add_on(sControlLookAddon); + sControlLookAddon = -1; + } + } + } + if (be_control_look == NULL) + be_control_look = new HaikuControlLook(); _init_global_fonts_(); @@ -1325,6 +1343,13 @@ _fini_interface_kit_() delete be_control_look; be_control_look = NULL; + // Note: if we ever want to support live switching, we cannot just unload + // the old one since some thread might still be in a method of the object. + // maybe locking/unlocking all loopers around would ensure proper exit. + if (sControlLookAddon >= 0) + unload_add_on(sControlLookAddon); + sControlLookAddon = -1; + // TODO: Anything else? return B_OK; @@ -1394,6 +1419,46 @@ preview_decorator(const BString& path, BWindow* window) } +/*! \brief queries the server for the current ControlLook path + \param path BString into which to store current ControlLook's add-on path + \return boolean true/false +*/ +bool +get_control_look(BString& path) +{ + BPrivate::AppServerLink link; + link.StartMessage(AS_GET_CONTROL_LOOK); + + int32 code; + if (link.FlushWithReply(code) != B_OK || code != B_OK) + return false; + + return link.ReadString(path) == B_OK; +} + + +/*! \brief Private function which sets the ControlLook for the system. + \param BString with the ControlLook add-on path to set + + Will return detailed error status via status_t +*/ +status_t +set_control_look(const BString& path) +{ + BPrivate::AppServerLink link; + + link.StartMessage(AS_SET_CONTROL_LOOK); + + link.AttachString(path.String()); + + status_t error = B_OK; + if (link.FlushWithReply(error) != B_OK) + return B_ERROR; + + return error; +} + + status_t get_application_order(int32 workspace, team_id** _applications, int32* _count) diff --git a/src/servers/app/DesktopSettings.cpp b/src/servers/app/DesktopSettings.cpp index c92f08c7b4..8226ed2780 100644 --- a/src/servers/app/DesktopSettings.cpp +++ b/src/servers/app/DesktopSettings.cpp @@ -293,6 +293,11 @@ DesktopSettingsPrivate::_Load() gSubpixelOrderingRGB = subpixelOrdering; } + const char* controlLook; + if (settings.FindString("control look", &controlLook) == B_OK) { + fControlLook = controlLook; + } + // colors for (int32 i = 0; i < kColorWhichCount; i++) { char colorName[12]; @@ -442,6 +447,8 @@ DesktopSettingsPrivate::Save(uint32 mask) settings.AddInt8("subpixel average weight", gSubpixelAverageWeight); settings.AddBool("subpixel ordering", gSubpixelOrderingRGB); + settings.AddString("control look", fControlLook); + for (int32 i = 0; i < kColorWhichCount; i++) { char colorName[12]; snprintf(colorName, sizeof(colorName), "color%" B_PRId32, @@ -785,6 +792,21 @@ DesktopSettingsPrivate::IsSubpixelOrderingRegular() const } +status_t +DesktopSettingsPrivate::SetControlLook(const char* path) +{ + fControlLook = path; + return Save(kAppearanceSettings); +} + + +const BString& +DesktopSettingsPrivate::ControlLook() const +{ + return fControlLook; +} + + void DesktopSettingsPrivate::_ValidateWorkspacesLayout(int32& columns, int32& rows) const @@ -939,6 +961,13 @@ DesktopSettings::IsSubpixelOrderingRegular() const return fSettings->IsSubpixelOrderingRegular(); } + +const BString& +DesktopSettings::ControlLook() const +{ + return fSettings->ControlLook(); +} + // #pragma mark - write access @@ -1059,3 +1088,10 @@ LockedDesktopSettings::SetSubpixelOrderingRegular(bool subpixelOrdering) fSettings->SetSubpixelOrderingRegular(subpixelOrdering); } + +status_t +LockedDesktopSettings::SetControlLook(const char* path) +{ + return fSettings->SetControlLook(path); +} + diff --git a/src/servers/app/DesktopSettings.h b/src/servers/app/DesktopSettings.h index 48677fb227..a87c6947c2 100644 --- a/src/servers/app/DesktopSettings.h +++ b/src/servers/app/DesktopSettings.h @@ -76,6 +76,8 @@ public: uint8 SubpixelAverageWeight() const; bool IsSubpixelOrderingRegular() const; + const BString& ControlLook() const; + protected: DesktopSettingsPrivate* fSettings; }; @@ -109,6 +111,8 @@ public: void SetSubpixelOrderingRegular( bool subpixelOrdering); + status_t SetControlLook(const char* path); + private: Desktop* fDesktop; }; diff --git a/src/servers/app/DesktopSettingsPrivate.h b/src/servers/app/DesktopSettingsPrivate.h index 9983e3a77d..0aae7a48cb 100644 --- a/src/servers/app/DesktopSettingsPrivate.h +++ b/src/servers/app/DesktopSettingsPrivate.h @@ -92,6 +92,9 @@ public: bool subpixelOrdering); bool IsSubpixelOrderingRegular() const; + status_t SetControlLook(const char* path); + const BString& ControlLook() const; + private: void _SetDefaults(); status_t _Load(); @@ -112,6 +115,7 @@ private: int32 fWorkspacesColumns; int32 fWorkspacesRows; BMessage fWorkspaceMessages[kMaxWorkspaces]; + BString fControlLook; server_read_only_memory& fShared; }; diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index c8cb05c284..4d524c18ab 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -697,6 +697,39 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) break; } + case AS_SET_CONTROL_LOOK: + { + STRACE(("ServerApp %s: Set ControlLook\n", Signature())); + + BString path; + status_t error = B_ERROR; + if (link.ReadString(path) == B_OK) { + LockedDesktopSettings settings(fDesktop); + error = settings.SetControlLook(path.String()); + } + + fLink.StartMessage(error); + fLink.Flush(); + break; + } + + case AS_GET_CONTROL_LOOK: + { + STRACE(("ServerApp %s: Get ControlLook\n", Signature())); + + if (fDesktop->LockSingleWindow()) { + DesktopSettings settings(fDesktop); + + fLink.StartMessage(B_OK); + fLink.AttachString(settings.ControlLook().String()); + fDesktop->UnlockSingleWindow(); + } else + fLink.StartMessage(B_ERROR); + + fLink.Flush(); + break; + } + case AS_CREATE_BITMAP: { STRACE(("ServerApp %s: Received BBitmap creation request\n",