Skip to content

Commit

Permalink
feat: style/color_scheme_dark: {string}, auto light/dark mode switchi…
Browse files Browse the repository at this point in the history
…ng for windows 10 1809+ (#1046)
  • Loading branch information
fxliang authored Dec 16, 2023
1 parent 415679b commit 5855aca
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 3 deletions.
76 changes: 73 additions & 3 deletions RimeWithWeasel/RimeWithWeasel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ RimeWithWeaselHandler::RimeWithWeaselHandler(UI *ui)
: m_ui(ui)
, m_active_session(0)
, m_disabled(true)
, m_current_dark_mode(false)
, m_show_notifications_when(SHOWN_ALWAYS)
, _UpdateUICallback(NULL)
{
Expand Down Expand Up @@ -107,6 +108,15 @@ void RimeWithWeaselHandler::Initialize()
{
_UpdateUIStyle(&config, m_ui, true);
_UpdateShowNotificationsWhen(&config, &m_show_notifications_when);
m_current_dark_mode = IsUserDarkMode();
if(m_current_dark_mode) {
const int BUF_SIZE = 255;
char buffer[BUF_SIZE + 1] = { 0 };
if (RimeConfigGetString(&config, "style/color_scheme_dark", buffer, BUF_SIZE)){
std::string color_name(buffer);
_UpdateUIStyleColor(&config, m_ui->style(), color_name);
}
}
m_base_style = m_ui->style();
}
_LoadAppOptions(&config, m_app_options);
Expand Down Expand Up @@ -160,6 +170,7 @@ UINT RimeWithWeaselHandler::AddSession(LPWSTR buffer, EatLine eat)
}
_UpdateUI(session_id);
m_active_session = session_id;
m_color_sync[session_id] = false;
return session_id;
}

Expand All @@ -170,6 +181,7 @@ UINT RimeWithWeaselHandler::RemoveSession(UINT session_id)
DLOG(INFO) << "Remove session: session_id = " << session_id;
// TODO: force committing? otherwise current composition would be lost
RimeDestroySession(session_id);
m_color_sync.erase(session_id);
m_active_session = 0;
return 0;
}
Expand All @@ -185,6 +197,44 @@ namespace ibus
};
}

void RimeWithWeaselHandler::UpdateColorTheme(BOOL darkMode)
{
RimeConfig config = { NULL };
if (RimeConfigOpen("weasel", &config))
{
if (m_ui)
{
_UpdateUIStyle(&config, m_ui, true);
m_current_dark_mode = darkMode;
if(darkMode) {
const int BUF_SIZE = 255;
char buffer[BUF_SIZE + 1] = { 0 };
if (RimeConfigGetString(&config, "style/color_scheme_dark", buffer, BUF_SIZE)) {
std::string color_name(buffer);
_UpdateUIStyleColor(&config, m_ui->style(), color_name);
}
}
m_base_style = m_ui->style();
}
_LoadAppOptions(&config, m_app_options);
RIME_STRUCT(RimeStatus, status);
if (RimeGetStatus(m_active_session, &status))
{
_LoadSchemaSpecificSettings(std::string(status.schema_id));
_LoadAppInlinePreeditSet(m_active_session, true);
_UpdateInlinePreeditStatus(m_active_session);
RimeFreeStatus(&status);
}
RimeConfigClose(&config);
}

RimeSetOption(m_active_session, "__synced", false);
_LoadAppInlinePreeditSet(m_active_session);
_UpdateInlinePreeditStatus(m_active_session);
for(auto &pair : m_color_sync)
pair.second = false;
}

BOOL RimeWithWeaselHandler::ProcessKeyEvent(KeyEvent keyEvent, UINT session_id, EatLine eat)
{
DLOG(INFO) << "Process key event: keycode = " << keyEvent.keycode << ", mask = " << keyEvent.mask
Expand Down Expand Up @@ -467,7 +517,25 @@ void RimeWithWeaselHandler::_LoadSchemaSpecificSettings(const std::string& schem

// load schema color style config
memset(buffer, '\0', sizeof(buffer));
if (RimeConfigGetString(&config, "style/color_scheme", buffer, BUF_SIZE))
if (!m_current_dark_mode && RimeConfigGetString(&config, "style/color_scheme", buffer, BUF_SIZE))
{
std::string color_name(buffer);
RimeConfigIterator preset = {0};
if(RimeConfigBeginMap(&preset, &config, ("preset_color_schemes/" + color_name).c_str()))
{
_UpdateUIStyleColor(&config, m_ui->style(), color_name);
}
else
{
RimeConfig weaselconfig;
if (RimeConfigOpen("weasel", &weaselconfig))
{
_UpdateUIStyleColor(&weaselconfig, m_ui->style(), std::string(buffer));
RimeConfigClose(&weaselconfig);
}
}
}
else if (m_current_dark_mode && RimeConfigGetString(&config, "style/color_scheme_dark", buffer, BUF_SIZE))
{
std::string color_name(buffer);
RimeConfigIterator preset = {0};
Expand Down Expand Up @@ -720,14 +788,16 @@ bool RimeWithWeaselHandler::_Respond(UINT session_id, EatLine eat)

// style
bool has_synced = RimeGetOption(session_id, "__synced");
if (!has_synced) {
if (!has_synced || !m_color_sync[session_id]) {
std::wstringstream ss;
boost::archive::text_woarchive oa(ss);
oa << m_ui->style();

actions.insert("style");
messages.push_back(std::string("style=") + wstring_to_string(ss.str().c_str(), CP_UTF8) + '\n');
RimeSetOption(session_id, "__synced", true);
if(!has_synced)
RimeSetOption(session_id, "__synced", true);
m_color_sync[session_id] = TRUE;
}

// summarize
Expand Down
11 changes: 11 additions & 0 deletions WeaselIPCServer/WeaselServerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "WeaselServerImpl.h"
#include <Windows.h>
#include <resource.h>
#include <WeaselUtility.h>

namespace weasel {
class PipeServer : public PipeChannel<DWORD, PipeMessage>
Expand Down Expand Up @@ -29,6 +30,7 @@ extern CAppModule _Module;

ServerImpl::ServerImpl()
: m_pRequestHandler(NULL),
m_darkMode(IsUserDarkMode()),
channel(std::make_unique<PipeServer>(GetPipeName(), sa.get_attr()))
{
m_hUser32Module = GetModuleHandle(_T("user32.dll"));
Expand Down Expand Up @@ -56,6 +58,15 @@ void ServerImpl::_Finailize()
}
}

LRESULT ServerImpl::OnColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if(IsUserDarkMode() != m_darkMode) {
m_darkMode = IsUserDarkMode();
m_pRequestHandler->UpdateColorTheme(m_darkMode);
}
return 0;
}

LRESULT ServerImpl::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// not neccessary...
Expand Down
3 changes: 3 additions & 0 deletions WeaselIPCServer/WeaselServerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ namespace weasel
MESSAGE_HANDLER(WM_CLOSE, OnClose)
MESSAGE_HANDLER(WM_QUERYENDSESSION, OnQueryEndSystemSession)
MESSAGE_HANDLER(WM_ENDSESSION, OnEndSystemSession)
MESSAGE_HANDLER(WM_DWMCOLORIZATIONCOLORCHANGED, OnColorChange)
MESSAGE_HANDLER(WM_COMMAND, OnCommand)
END_MSG_MAP()

LRESULT OnColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
Expand Down Expand Up @@ -79,6 +81,7 @@ namespace weasel
std::map<UINT, CommandHandler> m_MenuHandlers;
HMODULE m_hUser32Module;
SecurityAttribute sa;
BOOL m_darkMode;
};


Expand Down
3 changes: 3 additions & 0 deletions include/RimeWithWeasel.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class RimeWithWeaselHandler :
virtual void StartMaintenance();
virtual void EndMaintenance();
virtual void SetOption(UINT session_id, const std::string &opt, bool val);
virtual void UpdateColorTheme(BOOL darkMode);

void OnUpdateUI(std::function<void()> const &cb);

Expand Down Expand Up @@ -76,4 +77,6 @@ class RimeWithWeaselHandler :
const char* message_value);
static std::string m_message_type;
static std::string m_message_value;
std::map<UINT, BOOL> m_color_sync;
bool m_current_dark_mode;
};
1 change: 1 addition & 0 deletions include/WeaselIPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ namespace weasel
virtual void StartMaintenance() {}
virtual void EndMaintenance() {}
virtual void SetOption(UINT session_id, const std::string &opt, bool val) {}
virtual void UpdateColorTheme(BOOL darkMode) {}
};

// 處理server端回應之物件
Expand Down
14 changes: 14 additions & 0 deletions include/WeaselUtility.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ std::wstring WeaselUserDataPath();
const char* weasel_shared_data_dir();
const char* weasel_user_data_dir();

inline BOOL IsUserDarkMode()
{
constexpr const LPCWSTR key = L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
constexpr const LPCWSTR value = L"AppsUseLightTheme";

DWORD type;
DWORD data;
DWORD size = sizeof(DWORD);
LSTATUS st = RegGetValue(HKEY_CURRENT_USER, key, value, RRF_RT_REG_DWORD, &type, &data, &size);

if (st == ERROR_SUCCESS && type == REG_DWORD) return data == 0;
return false;
}

inline std::wstring string_to_wstring(const std::string& str, int code_page = CP_ACP)
{
// support CP_ACP and CP_UTF8 only
Expand Down

0 comments on commit 5855aca

Please sign in to comment.