Segfault in gtk_window_new - c

I have a simple GTK app written in C that segfaults on the line window = gtk_window_new(GTK_WINDOW_TOPLEVEL)
Here is the code:
#include <gtk/gtk.h>
int main(int argc, char **argv) {
GtkApplication *app = NULL;
GtkWidget *window = NULL;
app = gtk_application_new("com.github.Toothless204", G_APPLICATION_FLAGS_NONE);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_application_add_window(app, GTK_WINDOW(window));
int status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
I have googled around to find an answer but didn't find anything that actually provided an answer as to what the problem could be

Problem: tried to create a window before the GTK+ initialization functions was called by the GtkApplication.
Before using GTK+, you need to initialize it.
https://developer.gnome.org/gtk3/stable/gtk3-General.html
#include <gtk/gtk.h>
int main(int argc, char **argv) {
GtkWidget *window = NULL;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_show (window);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_main_quit), NULL);
gtk_main();
return 0;
}
For the same reason GtkApplication windows must be added after the GApplication 'startup' signal has been emitted.
https://wiki.gnome.org/HowDoI/GtkApplication
#include <gtk/gtk.h>
static void activate (GApplication *app, gpointer user_data) {
GtkWidget *window;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_application_add_window(GTK_APPLICATION(app), GTK_WINDOW(window));
gtk_widget_show (window);
}
int main (int argc, char **argv) {
GtkApplication *app;
int status;
app = gtk_application_new ("com.github.Toothless204", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}

Related

locale mismatch between gnuplot and gtk/c scripted output

I am coding a GUI (using GTK3) for a simple program that performs a simulation and plots the requested graph (using gnuplot).
When I'm using only gnuplot, I have no problem. The graph looks exactly like I want. However, when I try using this same code from GTK, it doesn't work anymore. It truncates all my value. Why ? What should I do to fix this?
This is the expected result (gnuplot without GTK):
And this is the actual result (gnuplot with GTK) :
#include <gtk/gtk.h>
static void
activate (GtkApplication* app,
gpointer user_data)
{
GtkWidget *window;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
gtk_widget_show_all (window);
FILE *gp = popen("gnuplot -persist", "w");
fprintf(gp, "plot '-' using 1:2 with lines\n");
int i;
for(i = 0; i < 13; i++){
fprintf(gp, "%d %f\n", i, 0.1*i);
}
pclose(gp);
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}

C: How to replace GtkAlignment function with newer GtkWidget align property

I am a new C programmer coming from Java. After reading some old books and articles, I've written the following code:
#include <gtk/gtk.h>
static void activate(GtkApplication* app, gpointer user_data) {
GtkWidget *window;
GtkWidget *button1;
GtkWidget *box;
box = gtk_alignment_new(0, 0, 0, 0);
window = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW(window), "Calculator");
gtk_window_set_default_size(GTK_WINDOW(window), 300, 400);
gtk_container_add(GTK_CONTAINER(window), box);
button1 = gtk_button_new();
gtk_button_set_label(GTK_BUTTON(button1), "1");
gtk_widget_set_size_request(button1, 40, 30);
gtk_container_add(GTK_CONTAINER(box), button1);
gtk_widget_show_all(window);
}
int main(int argc, char **argv) {
GtkApplication *app;
int status;
app = gtk_application_new("me.test.calculator", G_APPLICATION_FLAGS_NONE);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
The code compiles and runs correctly. The problem is that gtk_alignment_new is deprecated and I want to get rid of it.
I've tried replacing gtk_alignment_new with:
gtk_widget_set_halign(box, GTK_ALIGN_START);
gtk_widget_set_valign(box, GTK_ALIGN_START);
but the window does not show up when using this method. Thanks.
You want to set the halign/valign properties of the button (and then add the button straight into the window) to achieve the same functional results as your original code. 'box' is no longer needed at all.
Note that a GtkWindow is a GtkBin so only takes a single child: you will need to add additional containers in between to actually make a calculator. Maybe start by adding a GtkGrid as the sole window child and then attach all your buttons into the grid.
Using jku's advice I've written the following code which compiles and runs correctly without using gtk_alignment_new:
#include <gtk/gtk.h>
static void activate(GtkApplication* app, gpointer user_data) {
GtkWidget *window;
GtkWidget *button1;
GtkWidget *fixed;
fixed = gtk_fixed_new();
window = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW(window), "Calculator");
gtk_window_set_default_size(GTK_WINDOW(window), 300, 400);
gtk_container_add(GTK_CONTAINER(window), fixed);
button1 = gtk_button_new();
gtk_button_set_label(GTK_BUTTON(button1), "1");
gtk_widget_set_size_request(button1, 45, 35);
gtk_fixed_put(GTK_FIXED(fixed), button1, 5, 200);
gtk_widget_show_all(window);
}
int main(int argc, char **argv) {
GtkApplication *app;
int status;
app = gtk_application_new("me.test.calculator", G_APPLICATION_FLAGS_NONE);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
NOTE: I ended up using GtxFixed because the size of the window will be fixed as well.

C - GTK - g_application_quit

I have a problem with quitting a gtk application. The function call of g_application_quit results in the subsequent error:
GLib-GIO-CRITICAL **: g_application_quit: assertion 'G_IS_APPLICATION (application)' failed
The code snippet looks like this:
g_signal_connect(app_window, "destroy", G_CALLBACK(g_application_quit), app);
I tried this also, but still throws the same error:
g_signal_connect(app_window, "destroy", G_CALLBACK(g_application_quit), G_APPLICATION(app));
The app got initialized as:
GtkApplication *app = gtk_application_new("my.ne.sweeper", G_APPLICATION_FLAGS_NONE);
Any help is appreciated. Thank you.
You don't need to connect g_application_quit to window's destroy signal explicitly if You are using G_APPLICATION, it is done automatically.
Here goes the minimalistic example:
#include <gtk/gtk.h>
static void activate (GtkApplication* app, gpointer data) {
GtkWidget *window;
window = gtk_application_window_new(app);
gtk_window_set_default_size(GTK_WINDOW (window), 400, 200);
gtk_widget_show_all(window);
}
int main (int argc, char **argv) {
GtkApplication *app;
int status;
app = gtk_application_new("your.app.name", G_APPLICATION_FLAGS_NONE);
g_signal_connect(app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}

Unable to change cursor with GTK3

I am trying to change the cursor of a window dynamically with GTK3 but gtk_widget_get_parent_window doesn't seem to work.
Could someone please point out what I'm doing wrong? Thanks!
// https://developer.gnome.org/gtk3/stable/gtk-getting-started.html
// minimal example
#include <gtk/gtk.h>
static void
activate (GtkApplication* app,
gpointer user_data)
{
GtkWidget *window;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
// Here \/\/\/\/\/ .
GdkWindow* w = gtk_widget_get_parent_window(window);
GdkCursor* c = gdk_cursor_new_for_display(gdk_display_get_default(), GDK_WATCH);
gdk_window_set_cursor(w, c);
// /\/\/\/\/\ .
gtk_widget_show_all (window);
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
(main.exe:16508): Gdk-CRITICAL **: gdk_window_set_cursor: assertion
'GDK_IS_WINDOW (window)' failed
I am using GTK 3.16 with msys2
Many thanks in advance.
Extending #andlabs comment
Any attempt to change the cursor needs to be done after the widget has been added to the widget hierarchy or in GTK terms realized.
Calling gtk_widget_get_parent_window() or even gtk_widget_get_window() before a realize event has been fired for the widget will result in a NULL pointers in both cases.
Like #andlabs it is safer to use gtk_widget_get_window() in combination with a GtkWindow.
The solution.
static GdkWindow* G_WINDOW = 0;
static GdkCursor* G_CURSOR = 0;
// call after WindowRealize()
void changecursor()
{
assert(G_WINDOW != NULL);
gdk_window_set_cursor(G_WINDOW, G_CURSOR);
}
static void WindowRealize(GtkWidget *window, gpointer data)
{
G_CURSOR_HAND = gdk_cursor_new_for_display(gdk_display_get_default(), GDK_HAND2);
G_WINDOW = gtk_widget_get_window(window);
}
static void activate(GtkApplication* app,gpointer user_data)
{
GtkWidget *window = gtk_application_window_new(app);
...
g_signal_connect(window, "realize", G_CALLBACK(WindowRealize), NULL);
gtk_widget_show_all (window);
}

window always on top using xlib

I'm in the process of creating a gtk2 application which I would like drawn over all other apps at all times, I would rather use xlib to do that if it is possible
here's my code so far:
#include <gtk/gtk.h>
int main(int argc, char **argv)
{
gtk_init(&argc, &argv);
GtkWidget *mainwin;
mainwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_show_all (mainwin);
gtk_main ();
return 0;
}
I'd like to do this in the simplest manner possible
thanks
Yes it is possible and not complicated
#include <gtk/gtk.h>
int main(int argc, char **argv)
{
gtk_init(&argc, &argv);
GtkWidget *mainwin;
mainwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_keep_above ( (GtkWindow *) mainwin, TRUE);
gtk_widget_show_all (mainwin);
gtk_main ();
return 0;
}
gtk_window_set_keep_above does trick if window manager is cooperative.

Resources