Init wxApp from Linux daemon
-
- Earned some good credits
- Posts: 107
- Joined: Tue Aug 28, 2018 1:02 pm
- Location: Belarus
Re: Init wxApp from Linux daemon
The main purpose of my daemon is provide remote access to the system. It is used to accept client's connection to share application. When the application is shared I want to draw border around it. When user connects to view application's share daemon created separate thread which monitors application's windows state (size, position, overlapped or not, minimized or not, visible or not) and draws border around the app. Currently I use gtk to draw border, but there some problems with gtk, so I decided to draw border using wxWidgets. That why I need GUI-part in my daemon.
I'll try wxIMPLEMENT_APP_NO_MAIN. Are there some examples how to use it correctly?
I'll try wxIMPLEMENT_APP_NO_MAIN. Are there some examples how to use it correctly?
Re: Init wxApp from Linux daemon
but wxWidgets itself uses gtk to make controls and drawings.
i also don't understand why you need to pull wxWidgets with your code. Less dependencies - better to maintain.
wxWidgets it's not for border drawings. it's for rich user applications.
also better to split daemon and interface to separate apps and let them conversate via sockets.
i also don't understand why you need to pull wxWidgets with your code. Less dependencies - better to maintain.
wxWidgets it's not for border drawings. it's for rich user applications.
also better to split daemon and interface to separate apps and let them conversate via sockets.
ubuntu 20.04, wxWidgets 3.2.1
Re: Init wxApp from Linux daemon
http://bighow.org/questions/24837572/us ... idgets-3-0
see my comments inside, after '///'
so you must write body of secondary thread kinda
imho.
here are some words about it
https://docs.wxwidgets.org/3.0/group__ ... 6d57389af
see my comments inside, after '///'
but here everything works in main thread.The workaround is simple: you have to initialize SDL before wxWidgets (basically, before GTK). To achieve this, you have to change
wxIMPLEMENT_APP(GBEmu::MainApp);
to
wxIMPLEMENT_APP_NO_MAIN(GBEmu::MainApp);
so that wxWidgets doesn't hijack your main().
Then you have to create main() manually. In it, initialize SDL, then call wxEntry():
int main(int argc, char** argv) { ///This is a main function of your app
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { ///here they are calling some code they need
std::cerr << "Could not initialize SDL."; ///but wxWIdgets still not started
return 1;
}
return wxEntry(argc, argv); ///here they are starting wxWidgets and your wxWidgets code, and sit in there till exit
}
so you must write body of secondary thread kinda
Code: Select all
wxDECLARE_APP(MyGUI);
wxIMPLEMENT_APP_NO_MAIN(MyGUI);
//wxWidgets main thread body
int wxStart(){
return wxEntry(...); //starts wxWIdgets
}
//then in your daemon main(...)
int main(...){
....
std::thread(wxStart,...); //creates and starts wxWidgets in secondary thread
}
here are some words about it
https://docs.wxwidgets.org/3.0/group__ ... 6d57389af
ubuntu 20.04, wxWidgets 3.2.1
Re: Init wxApp from Linux daemon
now i m testing this code, it normally starts wxWidgets if wxStart(..) runs in main thread, but hangs being run from secondary thread.
Code: Select all
#include <thread>
DECLARE_APP(MyApp)
wxIMPLEMENT_APP_NO_MAIN(MyApp);
int wxStart(int argc, char** argv){
int dummy=0;
return wxEntry(dummy, static_cast<wxChar**>(nullptr)); //starts wxWIdgets
}
//then in your daemon main(...)
int main(int argc, char** argv) {
//wxDISABLE_DEBUG_SUPPORT();
//std::thread(wxStart, argc, argv); //here it hangs
wxStart(argc,argv); //here works normally
}
ubuntu 20.04, wxWidgets 3.2.1
Re: Init wxApp from Linux daemon
this code normally starts wxWIdgets in secondary thread
Code: Select all
#include <thread>
DECLARE_APP(MyApp)
wxIMPLEMENT_APP_NO_MAIN(MyApp);
int wxStart(int argc, char** argv){
return wxEntry(argc, argv); //starts wxWIdgets
}
int main(int argc, char** argv) {
//wxDISABLE_DEBUG_SUPPORT();
std::thread lt(wxStart, argc, argv); //creates and starts wxWidgets in secondary thread
lt.join();
return 0;
}
ubuntu 20.04, wxWidgets 3.2.1
-
- Earned some good credits
- Posts: 107
- Joined: Tue Aug 28, 2018 1:02 pm
- Location: Belarus
Re: Init wxApp from Linux daemon
Thanks for the snippet.
As I understand, MyApp is a class derived from wxApp? Can I use wxApp instead if I haven't got such class (MyApp)?
What I have now:
In .cpp file of my class that starts from main function of main thread:
In .cpp file of my class, which run in secondary thread and tries to create border instance:
However I see and error about undefined reference to wxGetApp().
As I understand, MyApp is a class derived from wxApp? Can I use wxApp instead if I haven't got such class (MyApp)?
What I have now:
In .cpp file of my class that starts from main function of main thread:
Code: Select all
int wxStart(int argc, char** argv)
{
return wxEntry(argc, argv);
}
DECLARE_APP(wxApp)
wxIMPLEMENT_APP_NO_MAIN(wxApp);
bool LinuxSessionHelperModule::BeforeMainProc(int argc, char* argv[])
{
atexit(ExitHandler);
XInitThreads();
CXErrorHandlerUtils::InstallErrorHandler();
// some unrelated init code here
std::thread(wxStart, argc, argv).detach();
return true;
}
Code: Select all
wxDECLARE_APP(wxApp);
LinuxDisplayHelperMaster::LinuxDisplayHelperMaster(const TDisplayId& displayId, bool showFrame, int borderThickness)
{
// some unrelated init code here
wxGetApp().CallAfter(
[this, borderThickness]
{
m_borderWindow = new LinuxBorderWindow(borderThickness);
m_borderWindow->Show(true);
}
);
}
Re: Init wxApp from Linux daemon
1. MyApp is an arbitrary name of your class derived from wxApp.
you must declare it, not wxApp!!! else you have created instance of base class. not yours.
so this code is wrong.
2. You cannot directly call anything from your daemon(main thread code) in your MyApp instance!
you can only send messages to it.
If you guarantee that this piece is working in secondary thread, where we started wxWidgets, then it's ok. so - where do you create an instance of this LinuxDisplayHelperMaster?
you must declare it, not wxApp!!! else you have created instance of base class. not yours.
so this code is wrong.
Code: Select all
DECLARE_APP(wxApp)
wxIMPLEMENT_APP_NO_MAIN(wxApp);
you can only send messages to it.
If you guarantee that this piece is working in secondary thread, where we started wxWidgets, then it's ok. so - where do you create an instance of this LinuxDisplayHelperMaster?
Code: Select all
wxDECLARE_APP(wxApp);
LinuxDisplayHelperMaster::LinuxDisplayHelperMaster(const TDisplayId& displayId, bool showFrame, int borderThickness)
{
// some unrelated init code here
wxGetApp().CallAfter(
[this, borderThickness]
{
m_borderWindow = new LinuxBorderWindow(borderThickness);
m_borderWindow->Show(true);
}
);
}
ubuntu 20.04, wxWidgets 3.2.1
-
- Earned some good credits
- Posts: 107
- Joined: Tue Aug 28, 2018 1:02 pm
- Location: Belarus
Re: Init wxApp from Linux daemon
So can I just create wxApp instance in LinuxSessionHelperModule and use it somehow in LinuxDisplayHelperMaster? Don't know actually how to access this instance from LinuxDisplayHelperMaster, but still...will it work?
I mean something like this:
May be I need call g_wxApp->OnInit() or something like that in separate thread?
And then in LinuxDisplayHelperMaster:
Code from LinuxDisplayHelperMaster is executed in secondary thread.
I mean something like this:
Code: Select all
bool LinuxSessionHelperModule::BeforeMainProc(int argc, char* argv[])
{
g_wxApp = new wxApp();
wxApp::SetInstance(g_wxApp);
return true;
}
And then in LinuxDisplayHelperMaster:
Code: Select all
LinuxDisplayHelperMaster::LinuxDisplayHelperMaster(const TDisplayId& displayId, bool showFrame, int borderThickness)
{
// some unrelated init code here
g_wxApp->CallAfter(
[this, borderThickness]
{
m_borderWindow = new LinuxBorderWindow(borderThickness);
m_borderWindow->Show(true);
}
);
}
Re: Init wxApp from Linux daemon
do not create anything by hands.
just correct your
DECLARE_APP(wxApp)
wxIMPLEMENT_APP_NO_MAIN(wxApp);
to your wxWdgets app name.
what is the current problem?
you do not see wxGetApp()? compiler or linker cannot see this reference?
if compiler -
put DECLARE_APP(wxApp) in some common header(how i know your file structure?).
if linker cannot see - than file where wxIMPLEMENT_APP_NO_MAIN(...) is written is not linked.
just correct your
DECLARE_APP(wxApp)
wxIMPLEMENT_APP_NO_MAIN(wxApp);
to your wxWdgets app name.
what is the current problem?
you do not see wxGetApp()? compiler or linker cannot see this reference?
if compiler -
put DECLARE_APP(wxApp) in some common header(how i know your file structure?).
if linker cannot see - than file where wxIMPLEMENT_APP_NO_MAIN(...) is written is not linked.
ubuntu 20.04, wxWidgets 3.2.1
Re: Init wxApp from Linux daemon
by the way, my attempt to replant wxWidgets to secondary thread has problems. sometimes strange errors occur, not existing with regular wxWidgets start. errors i see were issued by std:: vector instances, and may be defined as static. i have quite big multithreading application.
Do not know what exactly happens, but it could be somehow connected with static initialization of objects, which c++ runtime is douing before main(..) call.
Without further digging i just returned things back.
Do not know what exactly happens, but it could be somehow connected with static initialization of objects, which c++ runtime is douing before main(..) call.
Without further digging i just returned things back.
ubuntu 20.04, wxWidgets 3.2.1
Re: Init wxApp from Linux daemon
Hi,
This type of problem are usually shown when you trying to access the GUI in the secondary thread (where by secondary thread I mean the thread where no wxApp-derived class was created).
You need to create wxApp and all GUI in one thread.
Thank you.
This type of problem are usually shown when you trying to access the GUI in the secondary thread (where by secondary thread I mean the thread where no wxApp-derived class was created).
You need to create wxApp and all GUI in one thread.
Thank you.
Re: Init wxApp from Linux daemon
DECLARE_APP(wxApp)
wxIMPLEMENT_APP_NO_MAIN(wxApp);
are declarations.
I cannot "execute" them in any thread, except of main thread of application or thread which loads dll(if declare it in dll).
DECLARE_APP(..) is pure declation
wxIMPLEMENT_APP_NO_MAIN(...) - defines some variable and if it has constructor - application thread executes it before entering applicaion main(...).
ubuntu 20.04, wxWidgets 3.2.1