Glade, GtkBuiler or Gtk unexpectedly swapped a signal handler - c

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.

Related

Is there a way to caught signal when GtkEntryCompletion popped up?

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.

Passing user data to Callback function using glade

I am using glade to make my .ui files and then using GtkBuilder I am loading that whole .ui file in my C program, so all the widgets and stuff are created from the builder files itself.
Earlier I had been creating widgets only from the code itself, hence allowing me to pass any type of data to the Callback since the second argument is a gpointer variable and I could anytime create a pointer to a custom made structure and pass any type of data to the callbacks.
But now to connect to the signals I am just using this simple function :
gtk_builder_connect_signals(builder, NULL);
where builder is a pointer to GtkBuilder.
This connects all the signals mentioned in glade file with those of function defined in the .c files without having any provision of passing user_data other than that of Widgets (which themselves can only be defined in glade.)
Can anybody tell me a solution so that I can pass any type of data to my callbacks. I don't want to leave glade since it saves lot of my time, hence I would not like to switch over to traditional way of creating widgets by code only.
An example using both g_connect_signal() and gtk_builder_connect_signals() would be helpful. In this case which one to call first to override signal connection.
You can call gtk_builder_get_object to retrieve any widget created by Glade given the widget's name. Then you can connect the widget to the signals with the usual g_connect_signal API. The drawback is that you can no longer simply "mention" signals in the glade definition.
The other way is to also use gtk_builder_get_object to get the object, but to call g_object_set_qdata to associate the necessary user data with a GQuark key known to you. Your callback can then pick up the user data from the widget using g_object_get_qdata with the same key. This has the advantage that you would still be using gtk_builder_connect_signals.
That NULL pointer you are passing in is for the user data pointer.
gtk_builder_connect_signals(builder, NULL);
^
here----------------------------------|
If you always have the same user data object then your problem is solved. If not you
will need some kind of data structure for the different user data pointers so that
each callback can find the correct one.

GTKSDL - Handling events

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.

Replace the callback for a GtkItem created from a GtkItemFactoryEntry

I'm writing a plugin that's modifying an existing UI. One thing I want to do is change what an existing menu item does.
This is all using the Gtk library.
The menu item (a GtkItem) is created from a GtkItemFactoryEntry (which is out of my control), and has its current behaviour defined by the callback in the GtkItemFactoryEntry.
I can get handle on the menu item using gtk_item_factory_get_widget()
and attach further actions to the menu item using gtk_signal_connect(), but I can't seem to disconnect the original callback using gtk_signal_disconnect() or gtk_signal_disconnect_by_func().
Is there any way I can remove or replace the original callback?
So the hack I came up with was that, since signal handlers are id'ed by a one-up counter, and I get a handler id for the callback I want to attach with gtk_signal_connect() to just run gtk_signal_disconnect() on every handler id from zero to one less than my new handler id.
It's ugly, but it works. And since no other signals are hung on the item, it doesn't break anything.
g_signal_handlers_disconnect_matched() offers more options with which to match the callback you wish to disconnect.

"The calling thread must be STA, because many UI components require this." Error in WPF?

I am creating a xps document as below.
Assembly assembly = Assembly.GetExecutingAssembly();
//read embedded xpsDocument file
Stream helpStream = assembly.GetManifestResourceStream(resourceNameOfContext);
if (helpStream != null)
{
Package package = Package.Open(helpStream);
string inMemoryPackageName = "memorystream://" + topicName + ".xps";
Uri packageUri = new Uri(inMemoryPackageName);
//Add package to PackageStore
PackageStore.AddPackage(packageUri, package);
docXps = new XpsDocument(package, CompressionOption.Maximum, inMemoryPackageName);
}
return docXps;
When i am trying to get docXps.GetFixedDocumentSequence();
I am getting the above error. Can anyone help?
Thanks,
Your problem has nothing to do with the code surrounding the creation or use of the XPS document. It has everything to do with what thread you are running under.
You will receive the The calling thread must be STA, because many UI components require this error whenever any of the following are attempted on a MTA thread:
You construct any object derived from FrameworkElement (including Controls and Panels)
You construct any object derived from BitmapEffect
You construct any object derived from TextComposition
You construct any object derived from HwndSource
You access the current InputManager
You access the primary KeyboardDevice, StylusDevice, or TabletDevice
You attempt to change the focus on a FrameworkContentElement
You provide mouse, keyboard or IME input to any control that accepts text input
You make WPF content visible or update its layout
You manipulate the visual tree in such a way as to cause a re-evaluation for rendering
Several other changes, mostly having to do with display and input
For example, I received this error last year when I tried to deserialize some XAML that contained <Button> and other WPF objects from within a WCF service. The problem was simple to solve: I just switch to a STA thread to do the processing.
Obviously most work with XPS documents will trigger one or more of the above conditions. In your case I suspect that GetFixedDocumentSequence ends up using TextComposition or one of its subclasses.
No doubt the my solution of switching to a STA thread will also work for you, but first you need to figure out how your code that works with XpsDocuments is getting executed run from a MTA thread. Normally any code from from the GUI (eg a button press) is automatically run in a STA thread.
Is it possible that your code that manipulates XPS Documents may be being executed without a GUI? From a user-created thread? From a WCF service or a web service? From an ASPX page? Track that down and you'll probably find your solution.
If that doesn't work, let us know the details of the path through which GetFixedDocumentSequence is called, so we can diagnose it. The directly surrounding code isn't nearly as important as the call stack and how it is originally being invoked. If it is hard to explain you probably should add a call stack to prevent misunderstandings and help us diagnose the problem further, or tell you how to start a STA thread in your particular situation.
Is your code trying to access the xps doc from a background thread? If this is the case, you'll want to use the dispatcher. Info on that here.
If this doesn't help, could you post the code where you're actually calling GetFixedDocumentSequence()?

Resources