GTK application crashing when using GSK_RENDERER=Vulkan #10951
-
|
To reproduce: #include <gtk/gtk.h>
#include <gtk4-layer-shell.h>
#define APP_ID "com.example.LayerShellApp"
typedef struct {
GtkApplication parent;
GtkWindow *window;
GtkWidget *entry;
} LayerShellApp;
typedef struct {
GtkApplicationClass parent_class;
} LayerShellAppClass;
G_DEFINE_TYPE(LayerShellApp, layer_shell_app, GTK_TYPE_APPLICATION)
// Define the GObject type macros
#define LAYER_SHELL_APP_TYPE (layer_shell_app_get_type())
#define LAYER_SHELL_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), LAYER_SHELL_APP_TYPE, LayerShellApp))
static void
on_entry_changed(GtkEditable *editable, gpointer user_data G_GNUC_UNUSED)
{
const char *text = gtk_editable_get_text(editable);
g_print("Input changed: %s\n", text);
}
static void
on_entry_activate(GtkEntry *entry, gpointer user_data G_GNUC_UNUSED)
{
const char *text = gtk_editable_get_text(GTK_EDITABLE(entry));
g_print("Input activated: %s\n", text);
// Clear the entry after activation
gtk_editable_set_text(GTK_EDITABLE(entry), "");
}
static gboolean
on_key_pressed(GtkEventControllerKey *controller G_GNUC_UNUSED,
guint keyval,
guint keycode G_GNUC_UNUSED,
GdkModifierType state G_GNUC_UNUSED,
gpointer user_data)
{
LayerShellApp *app = LAYER_SHELL_APP(user_data);
// Hide window on Escape
if (keyval == GDK_KEY_Escape) {
gtk_widget_set_visible(GTK_WIDGET(app->window), FALSE);
return TRUE;
}
return FALSE;
}
static void
create_window(LayerShellApp *app)
{
if (app->window) {
return; // Window already exists
}
// Create the main window
app->window = GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(app)));
gtk_window_set_title(app->window, "Layer Shell App");
gtk_window_set_default_size(app->window, 400, 100);
// Initialize layer shell
gtk_layer_init_for_window(app->window);
// Set layer shell properties
gtk_layer_set_layer(app->window, GTK_LAYER_SHELL_LAYER_OVERLAY);
gtk_layer_set_keyboard_mode(app->window, GTK_LAYER_SHELL_KEYBOARD_MODE_EXCLUSIVE);
// Set anchors (center the window)
gtk_layer_set_anchor(app->window, GTK_LAYER_SHELL_EDGE_TOP, FALSE);
gtk_layer_set_anchor(app->window, GTK_LAYER_SHELL_EDGE_BOTTOM, FALSE);
gtk_layer_set_anchor(app->window, GTK_LAYER_SHELL_EDGE_LEFT, FALSE);
gtk_layer_set_anchor(app->window, GTK_LAYER_SHELL_EDGE_RIGHT, FALSE);
// Set margins to center the window
gtk_layer_set_margin(app->window, GTK_LAYER_SHELL_EDGE_TOP, 100);
gtk_layer_set_margin(app->window, GTK_LAYER_SHELL_EDGE_BOTTOM, 100);
gtk_layer_set_margin(app->window, GTK_LAYER_SHELL_EDGE_LEFT, 100);
gtk_layer_set_margin(app->window, GTK_LAYER_SHELL_EDGE_RIGHT, 100);
// Create the main container
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
gtk_widget_set_margin_top(vbox, 20);
gtk_widget_set_margin_bottom(vbox, 20);
gtk_widget_set_margin_start(vbox, 20);
gtk_widget_set_margin_end(vbox, 20);
gtk_window_set_child(app->window, vbox);
// Create the "Hi" label
GtkWidget *label = gtk_label_new("Hi!");
gtk_label_set_markup(GTK_LABEL(label), "<span size='large' weight='bold'>Hi!</span>");
gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
gtk_box_append(GTK_BOX(vbox), label);
// Create the text entry
app->entry = gtk_entry_new();
gtk_entry_set_placeholder_text(GTK_ENTRY(app->entry), "Type something...");
gtk_widget_set_hexpand(app->entry, TRUE);
gtk_box_append(GTK_BOX(vbox), app->entry);
// Connect entry signals
g_signal_connect(app->entry, "changed", G_CALLBACK(on_entry_changed), app);
g_signal_connect(app->entry, "activate", G_CALLBACK(on_entry_activate), app);
// Add key event controller for global key handling
GtkEventController *key_controller = gtk_event_controller_key_new();
gtk_widget_add_controller(GTK_WIDGET(app->window), key_controller);
g_signal_connect(key_controller, "key-pressed", G_CALLBACK(on_key_pressed), app);
}
static void
layer_shell_app_activate(GApplication *application)
{
LayerShellApp *app = LAYER_SHELL_APP(application);
// Create window if it doesn't exist
create_window(app);
// Toggle window visibility
if (gtk_widget_get_visible(GTK_WIDGET(app->window))) {
// Window is visible, hide it
gtk_widget_set_visible(GTK_WIDGET(app->window), FALSE);
g_print("Window hidden\n");
} else {
// Window is hidden, show it and focus the entry
gtk_window_present(app->window);
gtk_widget_grab_focus(app->entry);
g_print("Window shown\n");
}
}
static gint
layer_shell_app_command_line(GApplication *application, GApplicationCommandLine *command_line)
{
gint argc;
gchar **argv = g_application_command_line_get_arguments(command_line, &argc);
gboolean service_mode = FALSE;
// Check for service mode flag
for (int i = 1; i < argc; i++) {
if (g_strcmp0(argv[i], "--service") == 0) {
service_mode = TRUE;
break;
}
}
if (service_mode) {
// In service mode, just keep the application running
g_print("Running in service mode...\n");
g_application_hold(application);
} else {
// Normal mode - activate (toggle) the window
g_application_activate(application);
}
g_strfreev(argv);
return 0;
}
static void
layer_shell_app_init(LayerShellApp *app)
{
app->window = NULL;
app->entry = NULL;
}
static void
layer_shell_app_class_init(LayerShellAppClass *class)
{
GApplicationClass *app_class = G_APPLICATION_CLASS(class);
app_class->activate = layer_shell_app_activate;
app_class->command_line = layer_shell_app_command_line;
}
static LayerShellApp *
layer_shell_app_new(void)
{
return g_object_new(LAYER_SHELL_APP_TYPE,
"application-id", APP_ID,
"flags", G_APPLICATION_HANDLES_COMMAND_LINE,
NULL);
}
int
main(int argc, char *argv[])
{
LayerShellApp *app;
int status;
app = layer_shell_app_new();
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}And a script to re-open the application in a loop: #!/usr/bin/zsh
# Number of iterations
iterations=1000
# Delay in seconds (0.5 = 500ms)
delay=0.5
for ((i=1; i<=$iterations; i++)); do
echo "Running walker - iteration $i of $iterations"
/home/andrej/Documents/gtktest/builddir/layer-shell-app // CHANGE THIS
# Only sleep if not the last iteration
if [[ $i -ne $iterations ]]; then
sleep $delay
fi
done
echo "Completed all $iterations walker executions"The code causing this is It does not crash on Niri or Sway, so a Hyprland bug is very likely. |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 8 replies
-
|
Here's a |
Beta Was this translation helpful? Give feedback.
-
|
I've added |
Beta Was this translation helpful? Give feedback.
-
|
Hm... weird. I've completely wiped my hyprland config to make sure it's not some setting, but to no avail. It crashes rather reliably for me before 100 iterations with the script. And this does only happen on Hyprland. Niri and Sway work fine. This script crashes as well as Walker, but i wanted to exclude Walker as the culprit ... hence the C example. This here also seems to be related: linkfrg/dotfiles#77 |
Beta Was this translation helpful? Give feedback.
-
|
so yeah test |
Beta Was this translation helpful? Give feedback.

so yeah test