Replace the callback for a GtkItem created from a GtkItemFactoryEntry - c

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.

Related

GTK+/GLIB event loop and emit signal to event loop

I have one problem. I'm creating interface generation library, called libgreattao. It is able to using many backends to rendering GUI, while running in GUI mode. The problem is in GTK+2.0 backend. I must run main loop and on some event exits from it to destroy window in next step. On window's destroy event I will exit from main loop again - and do only this. Why I call main loop again? Because I must handle events created, while destroying window(window must destroy all it's control and hide). The problem is: callback for destroy signal is called once gtk_widget_destroy is called. I must ensure callback pass by application are called in main loop to allow exit from it, so I define custom signal for class GTKWIDGET. Of course, I can use workarounds, like destroying window in first signal type(the signal which ends main loop), but my library should works in any cases.
I have found solution, but not very good. I must add timeout event, which will emit my signal. I didn't find better solution yet.

What callback to use in CakePHP to catch all changes to model?

I want to add a new functionality to my application: executing a action every time a specific column is changed inside of a specific modal. This column is changed in many places in the application via several methods (save(), saveAll(), updateAll(), saveField()).
My first approach was to use the beforeSave/afterSave callbacks to handle this for every change on Modal level. However, I noticed that these callbacks aren't being done with updateAll() and saveField().
Is there a easy way to track all changes made to a specific column for a specific modal, regardless of the method being used in modal?
You can create your own callback and use it with save all, as described here

Keyboard events not working for second instance

I am facing a strange issue with keyboard event handling. I am able to use keyboard event on my screen for the first event. However, when I try for the second event it fails to execute.
e.g. For zoom, Ctrl+1 works only for the first time. Same happens when I try using some other event after the first one.
Note: It works absolutely fine if I use mouse events for above actions.
I am using
Actions action = actions.sendKeys(Keys.CONTROL, Keys.NUMPAD1);
action.perform();
I don't know how but when i when used "send keys" command two times and "perform "once it started to work.
However, this has happened with few keyboard events. Others work with single usage of send keys.
Actions action = actions.sendKeys(Keys.CONTROL, Keys.NUMPAD1);
Actions action = actions.sendKeys(Keys.CONTROL, Keys.NUMPAD1);
action.perform();

How do I run code in a thread that called a parameterless Application.Run()?

I want to render a chart with the DevExpress ChartControl via the WiForm DrawToBitmap() function on a separate thread.
I try something like:
Form yourForm;
Thread thread = new Thread( () =>
{
yourForm = new HiddenForm();
Application.Run(yourForm);
});
thread.ApartmentState = ApartmentState.STA;
thread.Start();
yourForm.Invoke(chartRenderingFunction)
And simple make sure the Hidden never actually gets displayed. However, I don't need that hidden form, and there is a parameterless form of Application.Run(). However, if I run that, it doesn't return. So my question is once I call Application.Run() inside a thread, how do I inject code in it?
Well, you actually really do need that hidden window. The only way to get code to run on that thread. Somebody must call PostMessage() and that requires a window handle. Your Invoke() call makes that call. You really should use BeginInvoke() instead, there's no point in starting a thread if you are going to wait for the call to complete.
Using Application.Run(yourForm) is going to make the window visible. You can stop it from becoming visible by overriding the SetVisibleCore() method in your HiddenForm class:
protected override void SetVisibleCore(bool value) {
if (!this.IsHandleCreated) {
CreateHandle();
value = false;
ThreadReady.Set();
}
base.SetVisibleCore(value);
}
The CreateHandle() call is necessary to make sure that the window is created so it can process the PostMessage() notifications. Also note the added AutoResetEvent (ThreadReady), you are going to have to call ThreadReady.WaitOne() after calling the thread's Start() method to ensure that your BeginInvoke() call is going to work. Dispose the form to get the thread to exit or call Application.Exit().
Last but not least, be very careful with using non-trivial controls on that thread. A chart control certainly is not indicated. You'll have long-lasting problems if that control uses the SystemEvents class for example. Your worker thread will get it to raise events on that worker thread. But it won't be around anymore after the chart is printed. You'll now get the events fired on an arbitrary threadpool thread, very nasty. A deadlock is a common mishap, particularly apt to trigger when locking the workstation.

Glade, GtkBuiler or Gtk unexpectedly swapped a signal handler

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.

Resources