Skip to content

Commit

Permalink
Use System::appName() to specify the window class on Windows and X11
Browse files Browse the repository at this point in the history
  • Loading branch information
dacap committed Jun 18, 2024
1 parent ca7739d commit 1e7482a
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 29 deletions.
4 changes: 3 additions & 1 deletion os/common/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class CommonSystem : public System {
CommonSystem();
~CommonSystem();

void setAppName(const std::string& appName) override { }
const std::string& appName() const override { return m_appName; }
void setAppName(const std::string& appName) override { m_appName = appName; }
void setAppMode(AppMode appMode) override { }

void markCliFileAsProcessed(const std::string& fn) override { }
Expand Down Expand Up @@ -79,6 +80,7 @@ class CommonSystem : public System {
void destroyInstance();

private:
std::string m_appName;
Ref<NativeDialogs> m_nativeDialogs;
#ifdef LAF_FREETYPE
std::unique_ptr<ft::Lib> m_ft;
Expand Down
1 change: 0 additions & 1 deletion os/none/os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ namespace os {

class NoneSystem : public System {
public:
void setAppName(const std::string& appName) override { }
void setAppMode(AppMode appMode) override { }

void markCliFileAsProcessed(const std::string& fn) override { }
Expand Down
15 changes: 10 additions & 5 deletions os/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,15 @@ namespace os {
virtual ~System() { }
public:

// Windows-specific: The app name at the moment is used to receive
// DDE messages (WM_DDE_INITIATE) and convert WM_DDE_EXECUTE
// messages into Event::DropFiles. This allows to the user
// double-click files in the File Explorer and open the file in a
// running instance of your app.
// The app name is used in several places.
//
// For X11 it's used for the WM_CLASS name of the main window.
//
// For Windows it's used for 1) the main window class name, and
// 2) to receive DDE messages (WM_DDE_INITIATE) and convert
// WM_DDE_EXECUTE messages into Event::DropFiles. This allows to
// the user double-click files in the File Explorer and open the
// file in a running instance of your app.
//
// To receive DDE messages you have to configure the registry in
// this way (HKCR=HKEY_CLASSES_ROOT):
Expand All @@ -76,6 +80,7 @@ namespace os {
//
// The default value of "HKCR\AppFile\shell\open\ddeexec\application"
// must match the "appName" given in this function.
virtual const std::string& appName() const = 0;
virtual void setAppName(const std::string& appName) = 0;

// We can use this function to create an application that can run
Expand Down
5 changes: 0 additions & 5 deletions os/win/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,6 @@ void SystemWin::setAppMode(AppMode appMode)
}
}

void SystemWin::setAppName(const std::string& appName)
{
m_appName = appName;
}

void SystemWin::setTabletOptions(const TabletOptions& options)
{
m_tabletOptions = options;
Expand Down
4 changes: 0 additions & 4 deletions os/win/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ class SystemWin : public CommonSystem {
WinAPI& winApi() { return m_winApi; }
WintabAPI& wintabApi() { return m_wintabApi; }

void setAppName(const std::string& appName) override;
std::string appName() const { return m_appName; }

void setTabletOptions(const TabletOptions& options) override;
TabletOptions tabletOptions() const override { return m_tabletOptions; }

Expand Down Expand Up @@ -56,7 +53,6 @@ class SystemWin : public CommonSystem {
void _setInternalMousePosition(const Event& ev);

private:
std::string m_appName;
TabletOptions m_tabletOptions;
WinAPI m_winApi;
WintabAPI m_wintabApi;
Expand Down
23 changes: 16 additions & 7 deletions os/win/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,6 @@

#include <algorithm>

// TODO the window name should be customized from the CMakeLists.txt
// properties (see LAF_X11_WM_CLASS too)
#define OS_WND_CLASS_NAME L"Aseprite.Window"

#define KEY_TRACE(...)
#define MOUSE_TRACE(...)
#define TOUCH_TRACE(...)
Expand Down Expand Up @@ -137,6 +133,17 @@ static BOOL CALLBACK log_monitor_info(HMONITOR monitor,
return TRUE;
}

std::wstring get_wnd_class_name()
{
if (auto sys = instance()) {
if (!sys->appName().empty())
return base::from_utf8(sys->appName());
}
// On Windows the class name cannot be empty, if we use an empty
// class the window class registration will fail.
return std::wstring(L"laf");
}

// Keys used to detect if the Windows 11 dark mode is selected.
static constexpr const char* kPersonalizeKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
static constexpr const char* kAppsUseLightThemeValue = "AppsUseLightTheme";
Expand Down Expand Up @@ -2501,9 +2508,10 @@ TabletAPI WindowWin::tabletAPI() const
void WindowWin::registerClass()
{
HMODULE instance = GetModuleHandle(nullptr);
const auto className = get_wnd_class_name();

WNDCLASSEX wcex;
if (GetClassInfoEx(instance, OS_WND_CLASS_NAME, &wcex))
if (GetClassInfoEx(instance, className.c_str(), &wcex))
return; // Already registered

wcex.cbSize = sizeof(WNDCLASSEX);
Expand All @@ -2516,7 +2524,7 @@ void WindowWin::registerClass()
wcex.hCursor = NULL;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOWFRAME+1);
wcex.lpszMenuName = nullptr;
wcex.lpszClassName = OS_WND_CLASS_NAME;
wcex.lpszClassName = className.c_str();
wcex.hIconSm = nullptr;

if (RegisterClassEx(&wcex) == 0)
Expand Down Expand Up @@ -2593,9 +2601,10 @@ HWND WindowWin::createHwnd(WindowWin* self, const WindowSpec& spec)
rc.h = CW_USEDEFAULT;
}

const auto className = get_wnd_class_name();
HWND hwnd = CreateWindowEx(
exStyle,
OS_WND_CLASS_NAME,
className.c_str(),
L"",
style,
rc.x, rc.y, rc.w, rc.h,
Expand Down
2 changes: 1 addition & 1 deletion os/win/wintab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class HandleSigSegv {

private:
static std::string getFilename() {
std::string appName = ((SystemWin*)os::instance())->appName();
std::string appName = os::instance()->appName();
return base::join_path(base::get_temp_path(),
appName + "-wintab32.crash");
}
Expand Down
14 changes: 9 additions & 5 deletions os/x11/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@

#define LAF_X11_DOUBLE_CLICK_TIMEOUT 250

// TODO the window name should be customized from the CMakeLists.txt
// properties (see OS_WND_CLASS_NAME too)
#define LAF_X11_WM_CLASS "Aseprite"

const int _NET_WM_STATE_REMOVE = 0;
const int _NET_WM_STATE_ADD = 1;

Expand Down Expand Up @@ -166,6 +162,14 @@ std::string decode_url(const std::string& in)
return out;
}

std::string get_x11_wm_class_name()
{
if (auto sys = instance())
return sys->appName();
// On X11 the class name can be empty.
return std::string();
}

} // anonymous namespace

// static
Expand Down Expand Up @@ -294,7 +298,7 @@ WindowX11::WindowX11(::Display* display, const WindowSpec& spec)
if (!m_window)
throw std::runtime_error("Cannot create X11 window");

setWMClass(LAF_X11_WM_CLASS);
setWMClass(get_x11_wm_class_name());

// Special frame for this window
if (spec.floating()) {
Expand Down

0 comments on commit 1e7482a

Please sign in to comment.