Skip to content

Instantly share code, notes, and snippets.

@kgilmer
Created December 31, 2021 04:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kgilmer/8ad2d6081b90cb9ca66c3d683211249b to your computer and use it in GitHub Desktop.
Save kgilmer/8ad2d6081b90cb9ca66c3d683211249b to your computer and use it in GitHub Desktop.
using Gtk;
const int KEY_CODE_ESCAPE = 65307;
const int KEY_CODE_ENTER = 65293;
/**
* This example demonstrates how to create a simple GTK dialog that operates independently from the window manager.
*
* The program collects input from the user. If the user presses enter, the entered text is returned to the caller.
* If the user presses escape, the program ends.
* If the user clicks the mouse out of the bounds of the window, the program ends.
*
* Compile with: valac --pkg gtk+-3.0 gtk-popup.vala
*/
int main (string[] args) {
Gtk.init (ref args);
// Create a POPUP window that operates independently of the window manager
var window = new Window (WindowType.POPUP);
window.window_position = WindowPosition.CENTER;
window.destroy.connect (Gtk.main_quit);
// Create a text widget on the window
Gtk.Entry entry = new Gtk.Entry ();
window.add (entry);
window.show_all ();
// Use the Gdk window to grab global inputs.
Gdk.Window gdkwin = window.get_window ();
var seat = grabInputs (gdkwin);
if (seat == null) {
stderr.printf ("Failed to aquire access to input devices, aborting.");
return 1;
}
// Handle mouse clicks by determining if a click is in or out of bounds
window.button_press_event.connect ((event) => {
int window_width = 0, window_height = 0;
window.get_size (out window_width, out window_height);
int mouse_x = (int) event.x;
int mouse_y = (int) event.y;
var click_out_bounds = ((mouse_x < 0 || mouse_y < 0) || (mouse_x > window_width || mouse_y > window_height));
if (click_out_bounds) {
quit (seat, window);
}
return !click_out_bounds;
});
// Handle key events: Enter and Escape
window.key_press_event.connect ((key) => {
bool handled = false;
switch (key.keyval) {
case KEY_CODE_ENTER:
handled = true;
stdout.printf (entry.get_text ());
quit (seat, window);
break;
case KEY_CODE_ESCAPE:
handled = true;
quit (seat, window);
break;
}
return handled;
});
Gtk.main ();
return 0;
}
void quit (Gdk.Seat seat, Window window) {
seat.ungrab ();
window.hide ();
window.close ();
}
// Grabs the input devices for a given window
Gdk.Seat ? grabInputs (Gdk.Window gdkwin) {
var display = gdkwin.get_display (); // Gdk.Display.get_default();
if (display == null) {
stderr.printf ("Failed to get Display\n");
return null;
}
var seat = display.get_default_seat ();
if (seat == null) {
stdout.printf ("Failed to get Seat from Display\n");
return null;
}
var grabStatus = seat.grab (gdkwin, Gdk.SeatCapabilities.ALL, true, null, null, null);
if (grabStatus != Gdk.GrabStatus.SUCCESS) {
stdout.printf ("Failed to grab input: %d\n", grabStatus);
return null;
} else {
return seat;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment