launcher that does something

This commit is contained in:
2025-07-07 22:54:17 +02:00
parent 27cd6a339d
commit 83aaaf65fa
17 changed files with 272 additions and 45 deletions

View File

@@ -1,15 +1,20 @@
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.10)
project(launcher) project(launcher)
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
enable_language(OBJC)
enable_language(OBJCXX)
endif ()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED YES) set(CMAKE_CXX_STANDARD_REQUIRED YES)
if (CMAKE_BUILD_TYPE STREQUAL "Debug") if (CMAKE_BUILD_TYPE STREQUAL "Debug")
# if (NOT DEFINED SANITIZE) # if (NOT DEFINED SANITIZE)
# set(SANITIZE YES) # set(SANITIZE YES)
# endif () # endif ()
endif () endif ()
if (SANITIZE STREQUAL "YES") if (SANITIZE STREQUAL "YES")

View File

@@ -1,15 +1,27 @@
add_executable(launcher add_executable(DhfsLauncher
src/LauncherApp.cpp src/LauncherApp.cpp
src/GLauncherApp.cpp src/GLauncherApp.cpp
src/LauncherAppMainFrame.cpp src/LauncherAppMainFrame.cpp
src/DhfsGuiInstance.cpp src/DhfsGuiInstance.cpp
src/DhfsGuiInstance.hpp src/DhfsGuiInstance.hpp
src/DhfsWxServer.cpp
src/DhfsWxServer.hpp
src/DhfsWxConnection.cpp
src/DhfsWxConnection.hpp
) )
target_link_libraries(launcher ${wxWidgets_LIBRARIES}) if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
target_link_libraries(launcher backend utils) target_sources(DhfsLauncher PRIVATE
src/macos/utils.m
src/macos/utils.h
)
endif ()
set_target_properties(launcher PROPERTIES
target_link_libraries(DhfsLauncher ${wxWidgets_LIBRARIES})
target_link_libraries(DhfsLauncher backend utils)
set_target_properties(DhfsLauncher PROPERTIES
MACOSX_BUNDLE TRUE MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_GUI_IDENTIFIER "com.usatiuk.dhfs.launcher" MACOSX_BUNDLE_GUI_IDENTIFIER "com.usatiuk.dhfs.launcher"
MACOSX_BUNDLE_BUNDLE_NAME "DHFS Launcher" MACOSX_BUNDLE_BUNDLE_NAME "DHFS Launcher"

View File

@@ -6,18 +6,19 @@
#include "LauncherAppMainFrame.h" #include "LauncherAppMainFrame.h"
DhfsGuiInstance::DhfsGuiInstance(LauncherAppMainFrame& parent): _parent(parent) { wxDEFINE_EVENT(NEW_LINE_OUTPUT_EVENT, wxCommandEvent);
wxDEFINE_EVENT(DHFS_STATE_CHANGE_EVENT, wxCommandEvent);
DhfsGuiInstance::DhfsGuiInstance(wxEvtHandler& parent): _evtHandler(parent) {
} }
void DhfsGuiInstance::OnStateChange() { void DhfsGuiInstance::OnStateChange() {
wxCommandEvent* event = new wxCommandEvent(DHFS_STATE_CHANGE_EVENT, _parent.GetId()); wxCommandEvent* event = new wxCommandEvent(DHFS_STATE_CHANGE_EVENT);
event->SetEventObject(&_parent); _evtHandler.QueueEvent(event);
_parent.GetEventHandler()->QueueEvent(event);
} }
void DhfsGuiInstance::OnRead(std::string s) { void DhfsGuiInstance::OnRead(std::string s) {
wxCommandEvent* event = new wxCommandEvent(NEW_LINE_OUTPUT_EVENT, _parent.GetId()); wxCommandEvent* event = new wxCommandEvent(NEW_LINE_OUTPUT_EVENT);
event->SetEventObject(&_parent);
event->SetString(std::move(s)); event->SetString(std::move(s));
_parent.GetEventHandler()->QueueEvent(event); _evtHandler.QueueEvent(event);
} }

View File

@@ -6,19 +6,19 @@
#define DHFSGUIINSTANCE_HPP #define DHFSGUIINSTANCE_HPP
#include "DhfsInstance.hpp" #include "DhfsInstance.hpp"
wxDECLARE_EVENT(NEW_LINE_OUTPUT_EVENT, wxCommandEvent);
class LauncherAppMainFrame; wxDECLARE_EVENT(DHFS_STATE_CHANGE_EVENT, wxCommandEvent);
class DhfsGuiInstance : public DhfsInstance { class DhfsGuiInstance : public DhfsInstance {
public: public:
DhfsGuiInstance(LauncherAppMainFrame& parent); DhfsGuiInstance(wxEvtHandler& parent);
void OnStateChange() override; void OnStateChange() override;
void OnRead(std::string s) override; void OnRead(std::string s) override;
protected: protected:
LauncherAppMainFrame& _parent; wxEvtHandler& _evtHandler;
}; };

View File

@@ -0,0 +1,21 @@
//
// Created by Stepan Usatiuk on 29.06.2025.
//
#include "DhfsWxConnection.hpp"
#include <iostream>
#include "wx/app.h"
#include "LauncherApp.h"
DhfsWxConnection::DhfsWxConnection() : wxConnection() {
}
bool DhfsWxConnection::OnExec(const wxString& wx_uni_char_refs, const wxString& wx_uni_chars) {
std::cout << "DhfsWxConnection::OnExec called with topic: " << wx_uni_char_refs << " and item: " << wx_uni_chars <<
std::endl;
wxGetApp().Open();
return true;
}

View File

@@ -0,0 +1,18 @@
//
// Created by Stepan Usatiuk on 29.06.2025.
//
#ifndef DHFSWXCONNECTION_HPP
#define DHFSWXCONNECTION_HPP
#include "wx/ipc.h"
class DhfsWxConnection : public wxConnection {
public:
DhfsWxConnection();
bool OnExec(const wxString&, const wxString&) override;
};
#endif //DHFSWXCONNECTION_HPP

View File

@@ -0,0 +1,11 @@
//
// Created by Stepan Usatiuk on 29.06.2025.
//
#include "DhfsWxServer.hpp"
#include "DhfsWxConnection.hpp"
wxConnectionBase* DhfsWxServer::OnAcceptConnection(const wxString& topic) {
return new DhfsWxConnection();
}

View File

@@ -0,0 +1,16 @@
//
// Created by Stepan Usatiuk on 29.06.2025.
//
#ifndef DHFSWXSERVER_HPP
#define DHFSWXSERVER_HPP
#include "wx/ipc.h"
class DhfsWxServer : public wxServer {
public:
wxConnectionBase* OnAcceptConnection(const wxString& topic) override;
};
#endif //DHFSWXSERVER_HPP

View File

@@ -53,7 +53,7 @@ MainFrame::MainFrame( wxWindow* parent, wxWindowID id, const wxString& title, co
m_panel1->SetSizer( bSizer2 ); m_panel1->SetSizer( bSizer2 );
m_panel1->Layout(); m_panel1->Layout();
bSizer2->Fit( m_panel1 ); bSizer2->Fit( m_panel1 );
m_notebook1->AddPage( m_panel1, _("Info"), true ); m_notebook1->AddPage( m_panel1, _("Info"), false );
m_panel3 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); m_panel3 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxGridSizer* gSizer1; wxGridSizer* gSizer1;
gSizer1 = new wxGridSizer( 1, 1, 0, 0 ); gSizer1 = new wxGridSizer( 1, 1, 0, 0 );
@@ -65,7 +65,7 @@ MainFrame::MainFrame( wxWindow* parent, wxWindowID id, const wxString& title, co
m_panel3->SetSizer( gSizer1 ); m_panel3->SetSizer( gSizer1 );
m_panel3->Layout(); m_panel3->Layout();
gSizer1->Fit( m_panel3 ); gSizer1->Fit( m_panel3 );
m_notebook1->AddPage( m_panel3, _("Logs"), false ); m_notebook1->AddPage( m_panel3, _("Logs"), true );
m_panel2 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); m_panel2 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer5; wxBoxSizer* bSizer5;
bSizer5 = new wxBoxSizer( wxVERTICAL ); bSizer5 = new wxBoxSizer( wxVERTICAL );
@@ -139,7 +139,7 @@ MainFrame::MainFrame( wxWindow* parent, wxWindowID id, const wxString& title, co
m_panel5 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); m_panel5 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_notebook1->AddPage( m_panel5, _("Web UI"), false ); m_notebook1->AddPage( m_panel5, _("Web UI"), false );
bSizer3->Add( m_notebook1, 1, wxEXPAND, 5 ); bSizer3->Add( m_notebook1, 1, wxBOTTOM|wxEXPAND|wxTOP, 5 );
this->SetSizer( bSizer3 ); this->SetSizer( bSizer3 );
@@ -148,6 +148,9 @@ MainFrame::MainFrame( wxWindow* parent, wxWindowID id, const wxString& title, co
this->Centre( wxBOTH ); this->Centre( wxBOTH );
// Connect Events // Connect Events
this->Connect( wxEVT_ACTIVATE, wxActivateEventHandler( MainFrame::OnActivate ) );
this->Connect( wxEVT_ACTIVATE_APP, wxActivateEventHandler( MainFrame::OnActivateApp ) );
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( MainFrame::OnClose ) );
m_notebook1->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( MainFrame::OnNotebookPageChanged ), NULL, this ); m_notebook1->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( MainFrame::OnNotebookPageChanged ), NULL, this );
m_notebook1->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, wxNotebookEventHandler( MainFrame::OnNotebookPageChanging ), NULL, this ); m_notebook1->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, wxNotebookEventHandler( MainFrame::OnNotebookPageChanging ), NULL, this );
m_startStopButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::OnStartStopButtonClick ), NULL, this ); m_startStopButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::OnStartStopButtonClick ), NULL, this );

View File

@@ -59,6 +59,9 @@ class MainFrame : public wxFrame
wxPanel* m_panel5; wxPanel* m_panel5;
// Virtual event handlers, override them in your derived class // Virtual event handlers, override them in your derived class
virtual void OnActivate( wxActivateEvent& event ) { event.Skip(); }
virtual void OnActivateApp( wxActivateEvent& event ) { event.Skip(); }
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnNotebookPageChanged( wxNotebookEvent& event ) { event.Skip(); } virtual void OnNotebookPageChanged( wxNotebookEvent& event ) { event.Skip(); }
virtual void OnNotebookPageChanging( wxNotebookEvent& event ) { event.Skip(); } virtual void OnNotebookPageChanging( wxNotebookEvent& event ) { event.Skip(); }
virtual void OnStartStopButtonClick( wxCommandEvent& event ) { event.Skip(); } virtual void OnStartStopButtonClick( wxCommandEvent& event ) { event.Skip(); }

View File

@@ -3,12 +3,6 @@
// //
// For compilers that don't support precompilation, include "wx/wx.h" // For compilers that don't support precompilation, include "wx/wx.h"
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
# include "wx/wx.h"
#endif
#include "wx/notebook.h" #include "wx/notebook.h"
#include "LauncherApp.h" #include "LauncherApp.h"
@@ -16,20 +10,34 @@
#include "LauncherAppMainFrame.h" #include "LauncherAppMainFrame.h"
#include "wx/taskbar.h" #include "wx/taskbar.h"
#include <wx/fileconf.h> #include <wx/fileconf.h>
#include "wx/snglinst.h"
IMPLEMENT_APP(LauncherApp) IMPLEMENT_APP(LauncherApp)
// This is executed upon startup, like 'main()' in non-wxWidgets programs. // This is executed upon startup, like 'main()' in non-wxWidgets programs.
bool LauncherApp::OnInit() { bool LauncherApp::OnInit() {
wxFileConfig::Get()->SetAppName("DHFS"); m_checker = new wxSingleInstanceChecker;
if (m_checker->IsAnotherRunning()) {
// wxLogError(_("Another program instance is already running, aborting."));
delete m_checker; // OnExit() won't be called if we return false
m_checker = NULL;
auto clinet = new wxClient();
auto conn = clinet->MakeConnection("dhfs", "/Users/stepus53/dhfs-sock", "dhfs");
conn->Execute("wakeup");
return false;
}
m_server.Create("/Users/stepus53/dhfs-sock");
wxFrame* frame = new LauncherAppMainFrame(NULL); wxFrame* frame = new LauncherAppMainFrame(NULL);
frame->Show(true); frame->Show(true);
SetTopWindow(frame); SetTopWindow(frame);
// wxTaskBarIcon* tb = new wxTaskBarIcon(); Bind(NEW_LINE_OUTPUT_EVENT, &LauncherApp::forwardEventToTopWindow, this);
// auto img = new wxImage(32, 32, false); Bind(DHFS_STATE_CHANGE_EVENT, &LauncherApp::forwardEventToTopWindow, this);
// img->Clear(128);
// tb->SetIcon(*(new wxBitmapBundle(*(new wxBitmap(*img)))), "e");
return true; return true;
} }
@@ -42,3 +50,41 @@ bool LauncherApp::OnExceptionInMainLoop() {
} }
return true; return true;
} }
int LauncherApp::OnExit() {
delete m_checker;
return wxApp::OnExit();
}
void LauncherApp::Open() {
if (m_topWindow) {
m_topWindow->SetFocus();
m_topWindow->Raise();
if (auto frame = dynamic_cast<wxFrame*>(m_topWindow)) {
frame->RequestUserAttention();
}
} else {
wxFrame* frame = new LauncherAppMainFrame(NULL);
frame->Show(true);
SetTopWindow(frame);
}
}
void LauncherApp::OnTopFrameClose(wxCloseEvent& event) {
SetTopWindow(nullptr);
}
void LauncherApp::forwardEventToTopWindow(wxCommandEvent& event) {
if (m_topWindow) {
m_topWindow->GetEventHandler()->ProcessEvent(event);
} else {
event.Skip();
}
}
#ifdef __APPLE__
void LauncherApp::MacReopenApp() {
this->Open();
}
#endif

View File

@@ -5,13 +5,38 @@
#ifndef HELLOWORLDAPP_H #ifndef HELLOWORLDAPP_H
#define HELLOWORLDAPP_H #define HELLOWORLDAPP_H
#include "DhfsGuiInstance.hpp"
#include "wx/wx.h"
#include "DhfsWxServer.hpp"
class wxSingleInstanceChecker;
// The HelloWorldApp class. This class shows a window // The HelloWorldApp class. This class shows a window
// containing a statusbar with the text "Hello World" // containing a statusbar with the text "Hello World"
class LauncherApp : public wxApp { class LauncherApp : public wxApp {
public: public:
virtual bool OnInit() override; virtual bool OnInit() override;
virtual int OnExit() override;
virtual bool OnExceptionInMainLoop() override; virtual bool OnExceptionInMainLoop() override;
#ifdef __APPLE__
void MacReopenApp() override;
#endif
void Open();
void OnTopFrameClose(wxCloseEvent& event);
private:
wxSingleInstanceChecker* m_checker = nullptr;
DhfsWxServer m_server;
void forwardEventToTopWindow(wxCommandEvent& event);
public:
DhfsGuiInstance m_dhfsInstance{*this};
}; };
DECLARE_APP(LauncherApp) DECLARE_APP(LauncherApp)

View File

@@ -5,10 +5,12 @@
#include <wx/stdpaths.h> #include <wx/stdpaths.h>
#include <filesystem> #include <filesystem>
#include "Exception.h" #ifdef __APPLE__
#include "macos/utils.h"
#endif
wxDEFINE_EVENT(NEW_LINE_OUTPUT_EVENT, wxCommandEvent); #include "LauncherApp.h"
wxDEFINE_EVENT(DHFS_STATE_CHANGE_EVENT, wxCommandEvent); #include "Exception.h"
std::string getBundlePath() { std::string getBundlePath() {
if (wxGetenv("DHFS_BUNDLE_PATH") == NULL) if (wxGetenv("DHFS_BUNDLE_PATH") == NULL)
@@ -39,10 +41,17 @@ LauncherAppMainFrame::LauncherAppMainFrame(wxWindow* parent)
wxFontWeight::wxFONTWEIGHT_NORMAL); wxFontWeight::wxFONTWEIGHT_NORMAL);
m_logOutputTextCtrl->SetFont(font); m_logOutputTextCtrl->SetFont(font);
updateState(); updateState();
#ifdef __APPLE__
SetAppAsRegular();
#endif
}
static DhfsInstance& getDhfsInstance() {
return wxGetApp().m_dhfsInstance;
} }
void LauncherAppMainFrame::updateState() { void LauncherAppMainFrame::updateState() {
switch (_dhfsInstance.state()) { switch (getDhfsInstance().state()) {
case DhfsInstanceState::RUNNING: { case DhfsInstanceState::RUNNING: {
m_statusText->SetLabel("Running"); m_statusText->SetLabel("Running");
m_startStopButton->SetLabel("Stop"); m_startStopButton->SetLabel("Stop");
@@ -53,24 +62,28 @@ void LauncherAppMainFrame::updateState() {
m_webView->LoadURL("http://localhost:8080"); m_webView->LoadURL("http://localhost:8080");
} }
wxGetApp().SetExitOnFrameDelete(false);
break; break;
} }
case DhfsInstanceState::STARTING: { case DhfsInstanceState::STARTING: {
m_statusText->SetLabel("Starting"); m_statusText->SetLabel("Starting");
m_startStopButton->SetLabel("Stop"); m_startStopButton->SetLabel("Stop");
m_statusBar1->SetStatusText("Starting", 0); m_statusBar1->SetStatusText("Starting", 0);
wxGetApp().SetExitOnFrameDelete(false);
break; break;
} }
case DhfsInstanceState::STOPPED: { case DhfsInstanceState::STOPPED: {
m_statusText->SetLabel("Stopped"); m_statusText->SetLabel("Stopped");
m_startStopButton->SetLabel("Start"); m_startStopButton->SetLabel("Start");
m_statusBar1->SetStatusText("Stopped", 0); m_statusBar1->SetStatusText("Stopped", 0);
wxGetApp().SetExitOnFrameDelete(true);
break; break;
} }
case DhfsInstanceState::STOPPING: { case DhfsInstanceState::STOPPING: {
m_statusText->SetLabel("Stopping"); m_statusText->SetLabel("Stopping");
m_startStopButton->SetLabel("Kill"); m_startStopButton->SetLabel("Kill");
m_statusBar1->SetStatusText("Stopping", 0); m_statusBar1->SetStatusText("Stopping", 0);
wxGetApp().SetExitOnFrameDelete(false);
break; break;
} }
default: default:
@@ -79,10 +92,10 @@ void LauncherAppMainFrame::updateState() {
} }
void LauncherAppMainFrame::OnStartStopButtonClick(wxCommandEvent& event) { void LauncherAppMainFrame::OnStartStopButtonClick(wxCommandEvent& event) {
switch (_dhfsInstance.state()) { switch (getDhfsInstance().state()) {
case DhfsInstanceState::RUNNING: case DhfsInstanceState::RUNNING:
case DhfsInstanceState::STARTING: { case DhfsInstanceState::STARTING: {
_dhfsInstance.stop(); getDhfsInstance().stop();
break; break;
} }
case DhfsInstanceState::STOPPED: { case DhfsInstanceState::STOPPED: {
@@ -94,7 +107,7 @@ void LauncherAppMainFrame::OnStartStopButtonClick(wxCommandEvent& event) {
options.jar_path = getBundlePath() + "/app/Server/quarkus-run.jar"; options.jar_path = getBundlePath() + "/app/Server/quarkus-run.jar";
options.webui_path = getBundlePath() + "/app/Webui"; options.webui_path = getBundlePath() + "/app/Webui";
_dhfsInstance.start(options); getDhfsInstance().start(options);
break; break;
} }
case DhfsInstanceState::STOPPING: { case DhfsInstanceState::STOPPING: {
@@ -149,3 +162,20 @@ void LauncherAppMainFrame::prepareWebview() {
m_webView->LoadURL("http://localhost:8080"); m_webView->LoadURL("http://localhost:8080");
m_panel5->Layout(); m_panel5->Layout();
} }
void LauncherAppMainFrame::OnActivate(wxActivateEvent& event) {
MainFrame::OnActivate(event);
}
void LauncherAppMainFrame::OnActivateApp(wxActivateEvent& event) {
MainFrame::OnActivateApp(event);
}
void LauncherAppMainFrame::OnClose(wxCloseEvent& event) {
#ifdef __APPLE__
SetAppAsAccessory();
#endif
wxGetApp().OnTopFrameClose(event);
MainFrame::OnClose(event);
}

View File

@@ -18,9 +18,6 @@ static constexpr auto kJavaHomeSettingsKey = "DHFS/JavaHome";
static constexpr auto kMountPointSettingsKey = "DHFS/MountDir"; static constexpr auto kMountPointSettingsKey = "DHFS/MountDir";
static constexpr auto kDataDirSettingsKey = "DHFS/DataDir"; static constexpr auto kDataDirSettingsKey = "DHFS/DataDir";
wxDECLARE_EVENT(NEW_LINE_OUTPUT_EVENT, wxCommandEvent);
wxDECLARE_EVENT(DHFS_STATE_CHANGE_EVENT, wxCommandEvent);
/** Implementing MainFrame */ /** Implementing MainFrame */
class LauncherAppMainFrame : public MainFrame { class LauncherAppMainFrame : public MainFrame {
protected: protected:
@@ -44,8 +41,15 @@ protected:
void updateState(); void updateState();
void unloadWebview(); void unloadWebview();
void prepareWebview(); void prepareWebview();
void OnActivate(wxActivateEvent& event) override;
void OnActivateApp(wxActivateEvent& event) override;
void OnClose(wxCloseEvent& event) override;
public: public:
/** Constructor */ /** Constructor */
LauncherAppMainFrame(wxWindow* parent); LauncherAppMainFrame(wxWindow* parent);
@@ -55,8 +59,6 @@ public:
private: private:
wxWebView* m_webView = nullptr; wxWebView* m_webView = nullptr;
wxGridSizer* m_webViewSizer; wxGridSizer* m_webViewSizer;
DhfsGuiInstance _dhfsInstance{*this};
}; };
#endif // __LauncherAppMainFrame__ #endif // __LauncherAppMainFrame__

View File

@@ -60,6 +60,9 @@
<property name="window_name">DHFS</property> <property name="window_name">DHFS</property>
<property name="window_style">wxTAB_TRAVERSAL</property> <property name="window_style">wxTAB_TRAVERSAL</property>
<property name="xrc_skip_sizer">1</property> <property name="xrc_skip_sizer">1</property>
<event name="OnActivate">OnActivate</event>
<event name="OnActivateApp">OnActivateApp</event>
<event name="OnClose">OnClose</event>
<object class="wxStatusBar" expanded="true"> <object class="wxStatusBar" expanded="true">
<property name="bg"></property> <property name="bg"></property>
<property name="context_help"></property> <property name="context_help"></property>
@@ -91,7 +94,7 @@
<property name="permission">none</property> <property name="permission">none</property>
<object class="sizeritem" expanded="true"> <object class="sizeritem" expanded="true">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxEXPAND</property> <property name="flag">wxBOTTOM|wxEXPAND|wxTOP</property>
<property name="proportion">1</property> <property name="proportion">1</property>
<object class="wxNotebook" expanded="true"> <object class="wxNotebook" expanded="true">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>

View File

@@ -0,0 +1,20 @@
//
// Created by Stepan Usatiuk on 29.06.2025.
//
#ifndef UTILS_H
#define UTILS_H
#ifdef __cplusplus
extern "C" {
#endif
void SetAppAsRegular(void);
void SetAppAsAccessory(void);
#ifdef __cplusplus
}
#endif
#endif //UTILS_H

View File

@@ -0,0 +1,11 @@
#import <Cocoa/Cocoa.h>
#import "utils.h"
void SetAppAsRegular(void) {
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
}
void SetAppAsAccessory(void) {
[NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
}