In a GTK2 application a user-defined callback function can be called when certain events occur, e.g., like this:
static void on_destroy(GtkObject* o) {
gtk_main_quit();
}
int main(int argc, char * argv[]) {
...
g_signal_connect(window1, "destroy", G_CALLBACK(on_destroy), NULL);
...
}
The signature of the callback functions depends on the type of signal or event. I was looking for an concise overview of those signatures and I found a chapter about signals in the GTK+ 2.0 tutorial. However, it seems to be missing the callback signatures for the GtkTreeview signals, like row-activated, select-cursor-row etc.
Are there any other sources that describe the correct implementation of all callback signatures, preferably in a concise overview and not spread out over several chapters?
You should check the Gtk+ 2 Reference Manual
For example, the destroy signal being connected in your example comes from one of the GtkWindow parent classes, GtkObject
The “destroy” signal
void user_function (GtkObject *object, gpointer user_data)
Check the Tree, List Widgets for relevant signals and respective prototypes:
https://developer-old.gnome.org/gtk2/stable/TreeWidgetObjects.html
Notice: Parent classes doesn't mean multiple inheritance, just a class above in the inheritance hierarchy.
You need to learn how to use the official help. On each widget help page, there's a navigation bar at the top. There you have direct links to the signals, the object hierarchy (parent classes), etc.
So if you're looking for a specific signal for a widget, you just go to that widget help page, then click on the "signals" link in the navigation bar. If the signal is not there, then it must be in a parent class. So you click on the "object hierarchy" link which sends you to the widget's inheritance tree. You click ont its parent and search for the signal again.
Alternatively, you may install the devhelp help browser that comes installed with your Linux distro (or in MSYS2 for Windows). There is a search field where you can just type the name of the symbol you're looking for, signals included.
Related
I have an application with a GtkEntry.
As a feature of the program, I use key-press-event signals on this entry for GDK_KEY_Up, GDK_KEY_Down, GDK_KEY_Return and GDK_KEY_KP_Enter. But the thing is I would like to disable these homemade functions when the GtkEntryCompletion shows completion popup items, in order to navigate in the completion list with the two arrows and to validate with entry keys.
To do this, I need a signal to tell me when I need to disable the homemade key-press-event, but the only signal availables with GtkEntryCompletion are:
void action-activated
gboolean cursor-on-match
gboolean insert-prefix
gboolean match-selected
void no-matches
Maybe there's another way to do it.
EDIT: I would like something equivalent to popup-shown from GtkComboBox I guess.
I wonder whether it is possible to understand which code pieces are executed on UI from source code just depending on static analysis in Windows Phone development.
I try to implement a static analysis finding places in which Dispatcher.(Begin)Invoke is used unnecessarily.
These are the places that UI thread definitely executes:
event handlers which gets "RoutedEventArgs" as a parameter
Constructors of UI elements
the definitions of method calls in above methods (means that transitively looking at call graphs of these event handler methods and UI constructors)
Is there any other place or is there something wrong about above list?
Every method called by using the Dispatcher or the right SynchronizationContext will execute on the UI thread. That makes exhaustive static analysis impossible. For instance, the callback of the WebClient class executes on the UI thread. How are you supposed to predict those corner cases?
A quick tip though, quite useful is you have a method that can be called both from a UI or a non-UI thread. By calling the method Dispatcher.CheckAccess() (this method isn't shown by the intellisense in Visual Studio, so it's hard to discover), you can know if you need to call the Dispatcher or not:
if (Dispatcher.CheckAccess())
{
// In the UI thread
SomeMethod();
}
else
{
// Not in the UI thread
Dispatcher.BeginInvoke(SomeMethod);
}
From there, you can write a wrapper:
public void CallDispatcherIfNeeded(Action method) // You might want a shorter name
{
if (Dispatcher.CheckAccess())
{
// In the UI thread
method();
}
else
{
// Not in the UI thread
Dispatcher.BeginInvoke(method);
}
}
And then you just have to call it, without worrying whether you're on the UI thread or not:
CallDispatcherIfNeeded(SomeMethod);
That said, if your code is correctly written, it's quite rare to need this kind of trick.
I would look at when Dispatcher.BeginInvoke is actually needed, not the other way around.
It is almost never needed, excepted when handing an async completed event which may start out on a background thread, and thus if you want to do something with the UI, you need to marshal it over to the UI thread.
In other words, unless you need to do something with the UI from a background thread, you don't need it.
Greg
In the GObject Reference Manual, it denotes that for a function:
g_signal_connect(instance, detailed_signal, c_handler, data)
A detailed_signal string parameter of form "signal-name::detail" is desired. My initial understanding of that is that there are predefined signal details to pass in. If that is the case, where can I find a list of these? If not, then what exactly does it mean, as the manual doesn't make that too terribly obvious.
The ::detail part of the signal name is optional. If a signal takes a detail parameter, then it will say so in the signal's documentation. Otherwise you can ignore it.
The only signal that I'm aware of that actually uses a detail parameter, is the notify signal of GObject. The notify signal without a detail fires whenever any property changes on the object, so it's fairly useless. But if you connect to the notify::visible signal, then it will fire whenever the object's visible property changes.
Unless things have changed a lot recently, there's no complete, official list of signals. The predefined signals depend entirely on what technologies you're using.
What you can do is look at the online documentation for the GObject instance classes you're working with. For instance, if you're working with GtkButton, you can look it up online and find out that it emits six signals (activate, clicked, enter, leave, pressed, released). GtkButton is derived from GtkContainer, which also emits several documented signals that can potentially be emitted by GtkButton. And GtkContainer is derived from GtkWidget, which emits many documented signals which can potentially be emitted by GtkButton.
If you find an object isn't emitting a kind of signal you expect, you might also look in the source code for that object, because sometimes objects emit undocumented signals,
For a 3D-modeling project I am using SDL and including in a GTK Widget (thanks to [GTKSDL], http://gtksdl.sourceforge.net "Direct Link to GTKSDL").
The widget is simply the loading of a .obj file with GTK and modeling it with OpenGL and then displaying it in the SDL Widget.
So far, everything is working.
The issue comes when I try to move the object in the widget using SDL events. Before the integration of the SDL window in GTK, the events were working without any troubles.
Also, once the 3D model is displayed, it is impossible for me to interact with GTK since apparently the event loop of SDL is waiting for something and whatever I do, it's not getting it.
I thought of forking the two event loop but it seems that GTK and SDL are trying to access the X server at the same time and it creates multiple conflicts.
I tried to remove the endless loop in SDL but it doesn't work too.
I am on Devian, I searched the internet for an implementation of "GTKSdl" but it seems outdated, any ideas how to patch it ?
UPDATE:
I'm already using SDLPollEvent and g_idle add.
So right after I choosed a file (with GTK), I fill the struct "t_stage" and use g_idle_add :
g_idle_add((GSourceFunc) &mainloop, stage);
gboolean mainloop(t_stage *stage)
{
SDL_Event evt;
while (SDL_PollEvent(&evt) != 0)
{
if (evt.type == SDL_MOUSEBUTTONDOWN)
on_mouse_down(stage, &(evt.button));
else if (evt.type == SDL_MOUSEBUTTONUP)
on_mouse_up(stage, &(evt.button));
else if (evt.type == SDL_MOUSEMOTION)
on_mouse_move(stage, &(evt.motion));
else if (evt.type == SDL_KEYDOWN)
handle_key(stage, evt.key.keysym.sym, 1);
else if (evt.type == SDL_KEYUP)
handle_key(stage, evt.key.keysym.sym, 0);
}
apply_keys(stage);
draw(stage, 0);
return (1);
}
But the events are still not received. Any ideas ?
GTKSDL seems to be an alpha-quality widget created back in 2001 and never maintained (nor widely used, I think). GTK has changed a lot since then, so I'm not sure it's the best solution for you.
However, one of the problems you're facing is that you can't use an endless loop inside an event handler in GTK (and the same is true for every event-driven toolkit using a message pump I know). If you do that, you just prevent GTK from getting a chance to process the pending events. For more information on how to solve this, give a look to Embedding SDL into GTK+
UPDATE:
g_idle_add allows to specify a callback and an argument to pass to that callback (the gpointer data argument). A gpointer is merely a pointer to void. You can pass it the address of a structure to read/write if you need your callback to be aware of several parameters.
In your callback registered with g_idle_add, you may read SDL events. Don't use SDL_WaitEvent for that because it will block until an SDL event occurred, use SDL_PollEvent (retrieves a pending event if any) or SDL_PeepEvents (retrieves all pending events if any). These functions are non-blocking, they return if no event is pending, whereas SDL_WaitEvent would block until an event is received.
You may then process the events, making sure it doesn't take too long until you exit the idele handler, otherwise the GTK UI will freeze. You may also prefer to just translate these events into GTK events and just dispatch them to GTK for it to process them.
You also have an old example of SDL integration with GTK 1.2. I think most of it would work with GTK 2, the basic idea is there, just need to update the code to replace symbols that were since then deprecated in GTK.
void
add_button_clicked(GtkButton * widget, GtkTreeView * treeview){
printf("%s\n",G_OBJECT_TYPE_NAME(widget));
} // Prints GtkTreeView
While the standard GtkButton:clicked signal is supposed to work like this (the widget itself followed by the user data) for some reason, the swapped signal handler has been called here and the two parameters are mixed up.
I could just shuffle the code around a bit to get past this but I would like to get to the bottom of why this is happening so I can fix/prevent it.
The glade swap checkbox is unchecked, and I didn't manually connect the signal anywhere, so I don't know why this is happening.
Edit: Ok, now it's happening to ALL my callbacks which is a big huge tremendous problem! Please help!
Edit: This "Feature" is apparently here so glade users can add a glade object to the callback and directly reference a gtk function so that they can for example hide a widget without having to write a single line of code. I'll roll with it.
Glade does this so that when you pass another object you can call a standard gtk function directly on it (Such as closing a window) without needing to write any code at all.