How to get X Window belonging to a GtkDrawingArea in gtk4? - gtk

I was trying to port GUI integration tutorial of gstreamer(https://gstreamer.freedesktop.org/documentation/tutorials/basic/toolkit-integration.html?gi-language=c) from gtk3 to gtk4. I am hitting an issue with getting the X window belonging to GtkDrawingArea. In gtk3, to get the XID and to pass it to GstVideoOverlay following approach is used:
static void realize_cb (GtkWidget *widget, CustomData *data) {
GdkWindow *window = gtk_widget_get_window (widget);
guintptr window_handle;
if (!gdk_window_ensure_native (window))
g_error ("Couldn't create native window needed for GstVideoOverlay!");
/* Retrieve window handler from GDK */
window_handle = GDK_WINDOW_XID (window);
/* Pass it to playbin, which implements VideoOverlay and will forward it to the video sink */
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (data->playbin), window_handle);
}
I'm not able to figure out how to do the same in Gtk4. Since Gtk4 is using Wayland terminology, the function in gdk to get XID is GDK_SURFACE_XID() which takes a GdkSurface* as an argument and there is no direct function in GtkWidget to get the pointer to the GdkSurface similar to gtk_widget_get_window in Gtk3.
I tried getting GtkNative using gtk_widget_get_native of the GtkDrawingArea and getting GdkSurface attached to it but that is returning the surface of the GtkWindow.
I am looking for a way to get XID to pass to gst_video_overlay_set_window_handle to be able to play video in the widget.
I am fairly new to both Gtk and Gstreamer so apologies for gaps in my understanding.

Related

UPROPOERTY variables not showing in details

I´ve been trying to show some variables that I created in a C++ class and then create a Blueprint class based on it. But when I see the details of the object or try to find this variables in the Blueprints they do not show up.
I´ve basically copy and paste code from UE4 documentation see here: https://docs.unrealengine.com/en-us/Programming/Introduction, but the variables are not showing up for me.
// MyActor.cpp
#include "MyActor.h"
// Sets default values
AMyActor::AMyActor()
{
//PrimaryActorTick.bCanEverTick = true;
TotalDamage = 200.0f;
}
// Called when the game starts or when spawned
void AMyActor::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AMyActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// MyActor.h
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"
UCLASS()
class MYPROJECT3_API AMyActor : public AActor
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere)
float TotalDamage;
// Sets default values for this actor's properties
AMyActor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};
I want to modify this variables from the Event Graph. Please help me find what I did wrong, if you need anymore information I will gladly provide it to you.
Use BlueprintReadWrite or BlueprintReadOnly
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float TotalDamage;
This just happened to me and feels like this is what might have happened to Juan Esteban as well, if you think your code is correct (and in my case it was):
"Hot Reloading" of the project was "stuck" in Unreal (i.e. changes made to the project didn't reflect in the editor), despite rebuilding the project and running "Refresh Visual Studio Project" from the file menu.
So... restarting Unreal actually fixed it.

I want to know about where "c" file generate after making GUI in Glide

i am using GTK3.0 library and Glade tool to build GUI using "c". can anyone tell me that after making GUI in Glade where actually "c" file generate.??
Glade doesn't generate code anymore. Old versions did, but the resulting code was unmaintable as you needed to edit the code generated, making it hard to change the UI afterwards.
Nowaday, you just use the GtkBuilder class to load the GUI description, as stated in the documentation.
/* Construct a GtkBuilder instance and load our UI description */
builder = gtk_builder_new ();
gtk_builder_add_from_file (builder, "builder.ui", NULL);
/* Connect signal handlers to the constructed widgets. */
window = gtk_builder_get_object (builder, "window");
Source: https://developer.gnome.org/gtk3/stable/ch01s03.html (official documentation)

how to map a gtk window to data

We're writing a diagnosis tool using GTK. You should watch several properties of different ojects, each in an own window. So you should be able to open several equal windows, each 'attached' to a specific object. When for example a button is clicked the appropriate GTK callback is called. But since all windows are equal there is no natural way to see which object should be altered. How could we map each window to its object in a good way?
Right now we use a map, mapping from the gtk windows to an object, but that feels more like a hack. Can we hand over the information about the object in a more elegant way?
GtkWindow is an indirect subclass of GObject, so you can use the family of functions g_object_set and g_object_get (and g_object_set_data, etc.).
I'm one of the team mentioned above looking for a solution. Here is what I got to work so far: I create a Gvalue object and want to add it to GTKWindow window.
int pid = 12345;
GValue val = G_VALUE_INIT;
g_value_init (&val, G_TYPE_INT);
g_value_set_int (&val, pid);
g_object_set (G_OBJECT(window), "pID", &val, NULL); //add to GTKWindow
When pressing a button in this window the following signalfunction is used:
extern "C" G_MODULE_EXPORT void onButtonStepClicked(GtkObject* caller, gpointer data){
GValue _pid;
GtkWidget* window = gtk_widget_get_toplevel (GTK_WIDGET(caller));
g_object_get_property(G_OBJECT(window), "processID", &_pid);
cout << (int)g_value_get_int(&pID) << endl;
}
But now i get the warning to my terminal:
GLib-GObject-WARNING **: g_object_set_valist: object class GtkWindow' has no property namedpID'
So i googled a while and found an example where i first have to install this Properties to a class. Does this makes sense, or did i miss something here?

Which is the best way to handle GtkMenu activate callback?

I have created a GtkMenu with 10 GtkMenuItems in it, and attached activate event to each menu item, but in callback function how should I get to know which menu item was actually selected?
I have added Call back to GtkMenuItem as follows:
gtk_signal_connect_object( GTK_OBJECT(menu_items), "activate",
GTK_SIGNAL_FUNC(on_option_selected),
(gpointer)GINT_TO_POINTER( i ) );
and my call back function is as follows:
gboolean on_option_selected( GtkWidget *widget, gpointer user_data );
And tried to convert user_data as follows but getting garbage.
gint selected_index = GPOINTER_TO_INT( user_data );
Thanks,
PP
The easiest way is to use the gpointer user_data argument to the callback to encode this, somehow.
You might for instance pass an enum, using the GINT_TO_POINTER() and GPOINTER_TO_INT() macros to convert back and forth. The enum might be something like
enum { FILE_NEW, FILE_OPEN, FILE_SAVE, FILE_SAVEAS, FILE_QUIT };
or similar. The connect (assuming recent GTK+ 2.x) should look like this:
g_signal_connect(G_OBJECT(item_saveas), "activate", G_CALLBACK(on_option_selected), GINT_TO_POINTER(FILE_SAVEAS));
Or you can go all out and use GtkActions, but that might feel like a bit too much engineering, depends on the number of commands you need to work with.
Don't use gtk_signal_connect_object(), it's deprecated and replaced by g_signal_connect_swapped(). You get garbage, because with both of those functions, the instance and user_data are switched around. So you are actually converting the pointer to menu_items to an integer. Use g_signal_connect() like unwind says.
However, since you're probably just going to do a switch(selected_index) after that, I'd recommend writing one callback function for each menu item (e.g. on_new_selected(), on_open_selected(), on_save_selected(), etc.) and connecting each one separately.

How do I find out what GDK events are required for a GTK+ signal?

I'm using Glade-3 for my GUI design, but I keep hitting this problem. I don't see anything in the GTK+ documentation mapping signals to events or in Glade-3 (3.4.5). Is there a place in the GTK+ source code to find this information?
Note: It is important in this question to recognize that events and signals are NOT the same thing in GTK.
Example:
I have an eventbox that requires the following events in order to receive the following signals. How do I determine what events are required by a given signal?
Events: GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK
Signals: leave_notify_event, enter_notify_event
Ok, I think I know what you mean now, I found this table matching up the gtk signals and gdk events. Here it is.
Assuming that I have interpreted your question correctly you are wanting to connect the signals you specified in the Glade file to the functions in the source code. How you do this depends if you are using libglade to load the files generate or GtkBuilder, both are similar but I will give samples in C just to be complete.
Using libglade you would do it like so:
GladeXml *xml = glade_xml_new(filename, NULL, NULL); // Load the file
glade_xml_signal_autoconnect(xml); // Connect the signals
Using GtkBuilder it would be like this:
GtkBuilder *xml = gtk_builder_new();
gtk_builder_add_from_file(xml, filename, NULL); // Load the file
gtk_builder_connect_signals(xml, NULL); // Connect the signals
When using GtkBuilder the second parameter in signal connect function can be replaced with a pointer to data which will then be passed to the signal handlers.
Going forward I would suggest using GtkBuilder as libglade is on its way to being deprecated.
Links
Here are the links to the relevent documentation about the two functions mentioned above
http://library.gnome.org/devel/libglade/stable/GladeXML.html#glade-xml-signal-autoconnect
http://library.gnome.org/devel/gtk/stable/GtkBuilder.html#gtk-builder-connect-signals
You can capture the events with gdk_event_handler_set()
First register your own GDK event handler on startup:
gdk_event_handler_set(my_gdk_event_handler, NULL, NULL);
... Then use it to print out any useful information, and don't forget to pass the event to GTK+ through gtk_main_do_event() like here:
void my_gdk_event_handler(GdkEvent *event, gpointer data)
{
printf("Received GdkEvent of type %d", event->type);
gtk_main_do_event(event); // Pass event to GTK+
}