Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorporate grestful DelegatePointer code into GtkD #137

Open
gnunn1 opened this issue Nov 28, 2015 · 2 comments
Open

Incorporate grestful DelegatePointer code into GtkD #137

gnunn1 opened this issue Nov 28, 2015 · 2 comments

Comments

@gnunn1
Copy link
Contributor

gnunn1 commented Nov 28, 2015

This is an enhancement request, I'm using some code from an open source application called grestful that enables using a delegate with the GTK idle thread processing instead of having to manage a C style function. I'd like to suggest that this code be incorporated into GtkD if you think it makes sense, I found it quite invaluable myself. The code is in the file at the following link:

https://github.com/Gert-dev/grestful/blob/master/Generic/Utility.d

This is a general utility module, the specific code I'm proposing be incorporated is at the end, from the DelegatePointer down to the end. The developer of the code is amenable to having it incorporated into GtkD, see the first reply to the bug request I filed here about a GC issue with the DelegatePointer that he helpfully fixed for me even though it didn't affect his application.

https://github.com/Gert-dev/grestful/issues/1

@MikeWey
Copy link
Member

MikeWey commented Nov 29, 2015

invokeDelegatePointerFunc seems to only work with c callbacks that only have a single data parameter. It would be interesting to see if it can be made more generic, so it works for all callbacks.

@ghost
Copy link

ghost commented Nov 29, 2015

Hello

I've upgraded the invokeDelegatePointerFunc function so it can also use a variable number of arguments. This seems to work fine, for example:

import gtkc.gtktypes;

// NOTE: The void* parameter at the end is omitted here as it's being used for the 
// delegate conversion. There is no need anymore for it anyways as you can freely
// pass in data into your delegate here.
auto callbackTuple = delegateToCallbackTuple(delegate(GtkTreeView*, GtkTreeViewColumn*, GtkTreeViewColumn*, GtkTreeViewColumn*) {
    return 1; // 1 means the drop can proceed, 0 means it can't.
});

someTreeView.setColumnDragFunction(callbackTuple.callback, callbackTuple.data, null);

this.t = callbackTuple.data; // Annoyance, see below.

So far there are still two annoyances that I haven't found a good solution for yet:

  • Callbacks can be executed at any time, this means someone has to ensure that the data passed to the C callback (which is the delegate pointer) does not get freed. The threadsAddIdleDelegate function already handles this by using GC.addRoot, but this also needs to happen for other types of functions. You can also handle this by assigning it to a class property (like in the example above), but letting the caller handle this every time is tedious.
  • This solution only works for GTK functions that require C callbacks that have a 'user data' parameter at the end of their parameter list. So far I haven't seen any callbacks that don't have a user data parameter or have it somewhere else than at the end, but I haven't used many of them so I wouldn't know for sure.

For the first item, would it be possible for GtkD to generate versions of methods such as setColumnDragFunction that automatically do the delegateToCallbackTuple and assign the callbackTuple.data to a protected member variable (there can only ever be one callback anyway)?

PS: It would be even neater if instead of having raw GTK pointers be passed to the delegate, it could automatically convert them to their corresponding D structures (i.e. gtk.TreeView.TreeView instead of GtkTreeView*, but that's beyond the scope of my implementation ;-).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants