Issue with Freeze() , Thaw() function in wxwidgets in linux - c++

I did project in window using wxwidgets then i am trying to run it linux but i am getting some problem with freeze&thaw function.
Will it work with linux? Is there any other option to freeze the window?
Here is mycode:
void *UpdateModeltreeThread::Entry()
{
m_PtrTree->Freeze();
m_PtrTree->ProcessUpdateModelTree();
m_PtrTree->Thaw();
return NULL;
}
Note: i am running above thing using wxThread
ProcessUpdateModelTree() in this function i am adding treeitems to wxtreelistctrl there are number of treeitems are there so i am using freeze&thaw,running at back end using thread function its working in windows but not in linux
Issue:In middle of Freeze() & Thaw() its calling paint event , because ot that its crashing in treelistctrl paint event,but this thing is not happing in window

You absolutely cannot call GUI methods such as Freeze() and Thaw() from worker threads, as you seem to be doing here. You must call them or, better, use safer wxWindowUpdateLocker from the main thread.

Related

Boost::process hide console on linux

According to this question : Boost::process hide console on windows
How can I achieve the same but on Linux platform using boost::process ? (prevent console window creation on the newly spawn child process)
My use case is as followed:
I'm trying to call a cross-platform GUI app built from .NET 5.0 AvaloniaUI (C#). And I'm calling that from another GUI app built from gtkmm (c++). It does create black console along with GUI window.
This symptom doesn't occur when I tried calling the same mentioned Avalonia app with another cross-platform Avalonia app. It doesn't create any console, only the GUI window as intended. (Using System.Diagnostics.Process from .NET C#).
So maybe there is some detail behind that make these api behave differently? (boost::process / System.Diagnostics.Process)
Basically I'm looking for the api to do the same thing with System.Diagnostics.Process (C#) on c++
On linux a new console isn't created anyways. So, the only thing you might want to do is prevent the child process from sharing the parent's, like so:
#include <boost/process.hpp>
namespace bp = boost::process;
int main() {
bp::child child(bp::search_path("xclock"), //
bp::std_in.null(), //
bp::std_out.null(), //
bp::std_err.null());
child.wait();
}
If, on the other hand, you would like to create a terminal, you have to tell the OS which one you want and how to start that:
bp::child child(bp::search_path("gnome-terminal"), //
std::vector<std::string>{"-x", "/usr/bin/htop"}, //
bp::std_in.null(), //
bp::std_out.null(), //
bp::std_err.null());
Or, e.g.
bp::child child(bp::search_path("gnome-terminal"), //
std::vector<std::string>{"-x", "/usr/bin/htop"}, //
bp::std_in.null(), //
bp::std_out.null(), //
bp::std_err.null());
Note that the gnome-terminal launcher forks (so it "returns" immediately, leaving the terminal running with the htop inside), but xterm does not. So, on UNIX, like ever, you have lots of choices.
Linux does not create new console, like the others suggested. (unless explicitly define to)
After more investigation, I found that, it's only a misunderstanding.
If you use some GUI lib (like GTKmm, in this case), and try to spawn new process, which is a GUI window also, there might be an afterimage-like effect if you don't do it asynchonously
(If that second GUI window is initialized with black background, like the one created with AvaloniaUI, you may confuse it as another console :p)

Propper way to deinitialize GTK

I'm writing a c++ application that creates a GTK3 window at some point, while also running X11 code in other places.
For the pure X11 part i'm using XOpenDisplay() to open a display.
Running the X11 part and opening a GTK window afterwards works fine. Also running the X11 part multiple times is no problem as i release the display there using XCloseDisplay.
The problem i'm facing occurs when i try to run the X11 code after gtk has been initialized (to be more specific, calling XOpenDisplay() after the gtk initialization).
I'm suspecting that after running gtk_init() the display is never being released, even after gtk_main_quit().
I didn't find anything about deinitialization in the gtk3 documentation. Is there any way to propperly deinitialize gtk or free the display in another way?
The solution was completely unrelated. I was setting the DISPLAY environment variable twice by accident. Apparently gtk can handle this but XOpenDisplay crashes.
I have added a test to only set it once, now everything works. Perhaps gtk does propperly deinitialize after gtk_main_quit()

wxWidgets (or even OOP GUI) Multiple Windows

I'm kind of stuck on something; regarding spawning multiple forms in OOP.
The message loop most of the time is (wxWidget's case) window->show();
bool MyApp::OnInit()
{
MainWindow *oWindow = new MainWindow(wxT("My Window"));
oWindow->Show(true);
return true;
}
Others have oWindow->run(), but anyway my question is:
I've created a second thread with the exact same structure of the function above and called the message loop method. The problem is that the window appears and dissapears suddenly which doesn't make sense to me. If however I call:
MainWindow *oWindow = new MainWindow(wxT("My Window"));
oWindow->Show(true);
MainWindow *oWindow2 = new MainWindow(wxT("My Window"));
oWindow2->Show(true);
It will work, but I don't want that as I will need to keep track of the windows I create and have them on separate threads. What can I do?
You cannot run wxWidgets windows in anything other than the main thread.
"GUI calls, such as those to a wxWindow or wxBitmap are explicitly not safe at all in secondary threads and could end your application prematurely. This is due to several reasons, including the underlying native API and the fact that wxThread does not run a GUI event loop similar to other APIs as MFC."
http://docs.wxwidgets.org/2.8/wx_wxthread.html
BTW, I cannot imagine any situation where what you want to do is a good idea. There is never any need to tun windows in more than one thread.
A windows program is event-driven. You can as have as many top level windows as you want, but there should be just one event queue so that the events on two windows do not end up in contention for the same resource. This is why wxWidgets prevents you trying to create two threads both handling windows events.

Gtkmm: Adding Window at later time

Because I´m writting a "generic" application behaving completely different when facing other configurations, I´m forced to show gtk windows even if I dont yet know them at startup. There might also be the requirement that multiple windows need to be visisble (not modal dialogs but standalone windows) at the same time. But, it would be great if one can simply start one gtk event loop at startup.
Is is somehow possible to add windows to that loop after it has been started?
While I found the Gtk::Application class which seems to support exactly the indented behaviour I´m restricted to use the Gtk::Main class.
There's only a single Gtk::Main object allowed. Widgets should be created in the same thread the main event loop is being run in. To work around this limitation you need to develop a way to pass your window creation commands to the gtk thread.
The simplest way is to use Glib::Dispatcher
struct WindowBuilder {
/**/
Glib::Dispatcher* signal_create;
void create_window() {
//From main thread...
signal_create->emit();
}
}
void create_mainWnd() {
new Ui::MainWnd();
}
//From Gtk thread...
builder->signal_create->connect(sigc::ptr_fun(create_mainWnd));
Gtk::Main::run();
Glib::Dispatcher doesn't take any arguments with it, so next step is to figure out how to pass arguments around between threads.
For different types of windows you can just use different disptachers.
boost::asio::io_service can help you pass messages around.
while(!exit) {
io_service.reset();
io_service.poll();
while(Gtk::Main::events_pending())
Gtk::Main::iteration();
Sleep(0);
}

How do I use GTK and glut together?

I know that in order to write a GTK application, I write a bunch of code which describes what is put in the main window, then I call:
gtk_main();
Any code statements after this do not get executed.
Now let's suppose I'd like my GTK app to display something I wrote with glut, which itself contains a bunch of statements about what graphics need to be set etc. then ends with the statement:
glutMainLoop();
Anything after this is not executed.
So my problem is that either of these two statements prevents me from calling the other.
Is there a way to execute a glut main loop inside a GTK widget ?
Is there a way to write a code that could somehow simultaneously call both a GTK main loop and a glut main loop (but called from the main program and rendered in a separate X window, not within a widget)? I've got a feeling this could be done with "threads"...
You don't. There's generally no point to it.
GLUT is a library for creating and managing OpenGL windows. GTK already has an OpenGL window in it. If you're using GTK, then there's no point in using GLUT. It's like having two vector math libraries or something.
You are running the main loops. gtk_main() runs until gtk_quit() is called.
gtk_main() at GTK.org
Runs the main loop until gtk_main_quit() is called. You can nest calls to gtk_main(). In that case gtk_main_quit() will make the innermost invocation of the main loop return.
Also, glutMainLoop() works the same way, it processes GL events forever.
glutMainLoop() at OpenGL.org
glutMainLoop() enters the GLUT event processing loop. This routine should be called at most once in a GLUT program. Once called, this routine will never return. It will call as necessary any callbacks that have been registered.
So, you you wan't both of these things to execute at the same time (I think they might interfere with each other so you might get unexpected results) then you will need to call gtk_main_iteration() from inside glut.
gtk_main_iteration() at GTK.org
Runs a single iteration of the mainloop. If no events are waiting to be processed GTK+ will block until the next event is noticed. If you don't want to block look at gtk_main_iteration_do() or check if any events are pending with gtk_events_pending() first.
Now.. GLUT doesn't have an equivalent to gtk_main_iteration() so you are going to need to register GLUT callbacks.
You could register a callback with GLUT that runs gtk_main_iteration() using glutIdleFunc(void (*func)(void)) which will run a callback for every frame - glutIdleFunc()..
Or you could give a callback to glutTimerFunc(unsigned int msecs,
void (*func)(int value), value) to call and check the return value of gtk_main_iteration() every 200msec or so.
I'd probably experiment with both, glutIdleFunc() might not always get called regularly enough for good responsiveness.
It really is worth looking at driving GTK's GL support though.