Skip to content

Instantly share code, notes, and snippets.

@digitalsignalperson
Created January 22, 2025 08:41
Show Gist options
  • Save digitalsignalperson/9f6bc16ba1954c40cb61ca4babc8c419 to your computer and use it in GitHub Desktop.
Save digitalsignalperson/9f6bc16ba1954c40cb61ca4babc8c419 to your computer and use it in GitHub Desktop.
using casilda with gtk4-layer-shell for drop-down terminal
// toggle visibility with `kill -USR1 $(cat /tmp/casilda-tty.pid)` (assign this as the cmdline for a global hotkey)
#include "gtk4-layer-shell.h"
#include <gtk/gtk.h>
#include "casilda-compositor.h" // https://gitlab.gnome.org/jpu/casilda
#include <unistd.h>
#include <glib-unix.h>
GtkWidget *window;
#define TTY_SOCKET "/tmp/casilda-tty.sock"
#define TTY_PID "/tmp/casilda-tty.pid"
static gboolean on_signal_usr1(gpointer user_data) {
if (window) {
bool visible = !gtk_widget_get_visible(window);
gtk_widget_set_visible(window, visible);
}
return G_SOURCE_CONTINUE;
}
static void activate (GtkApplication *app, G_GNUC_UNUSED gpointer user_data)
{
CasildaCompositor *compositor;
window = gtk_application_window_new (app);
GtkWindow* gtk_window = GTK_WINDOW(window);
gtk_layer_init_for_window(gtk_window);
gtk_layer_set_layer(gtk_window, GTK_LAYER_SHELL_LAYER_TOP);
// gtk_layer_auto_exclusive_zone_enable(gtk_window);
gtk_layer_set_keyboard_mode(gtk_window, GTK_LAYER_SHELL_KEYBOARD_MODE_ON_DEMAND);
gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_LEFT, 20);
gtk_layer_set_margin(gtk_window, GTK_LAYER_SHELL_EDGE_RIGHT, 20);
gtk_layer_set_anchor(gtk_window, GTK_LAYER_SHELL_EDGE_TOP, TRUE);
gtk_window_set_title(GTK_WINDOW (window), "Compositor");
gtk_window_set_default_size(GTK_WINDOW (window), 1000, 600); // larger than 1000x600 some kind of limit??
compositor = casilda_compositor_new(TTY_SOCKET);
gtk_window_set_child(GTK_WINDOW (window), GTK_WIDGET (compositor));
gtk_window_present(GTK_WINDOW (window));
g_unix_signal_add(SIGUSR1, on_signal_usr1, NULL);
GError *error = NULL;
GSpawnFlags flags = G_SPAWN_DO_NOT_REAP_CHILD;
gchar *argv[] = {"/usr/bin/ghostty", "--fullscreen", NULL};
gchar *envp[] = {"GDK_BACKEND=wayland", "WAYLAND_DISPLAY=" TTY_SOCKET, NULL};
GPid child_pid;
if (!g_spawn_async(NULL, argv, envp, flags, NULL, NULL, &child_pid, &error)) {
g_printerr("Failed to spawn process: %s\n", error->message);
g_error_free(error);
g_application_quit(G_APPLICATION(app));
return;
}
g_child_watch_add(child_pid, (GChildWatchFunc)g_application_quit, app);
}
int main(int argc, char **argv) {
g_autoptr(GtkApplication) app = NULL;
app = gtk_application_new("org.gnome.casilda.compositor", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect(app, "activate", G_CALLBACK (activate), NULL);
FILE *file = fopen(TTY_PID, "w");
if (file) {
fprintf(file, "%d\n", getpid());
fclose(file);
g_print("PID written to %s\n", TTY_PID);
} else {
perror("Failed to write PID file");
}
return g_application_run(G_APPLICATION (app), argc, argv);
}
@digitalsignalperson
Copy link
Author

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