I'm on macOS. Slightly modifying the first example snippet here by calling gtk_window_present
repeatedly in a timeout, we get:
#include <gtk/gtk.h>
static gboolean timeout_callback (gpointer window) {
printf("timeout\n");
gtk_window_present (GTK_WINDOW (window));
return TRUE;
}
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);
g_timeout_add(1000, timeout_callback, window);
gtk_window_present (GTK_WINDOW (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;
}
However, the window does not actually come to the foreground. How do I raise the main gtk+ window to the front in macOS / OS X?
According to Paul Davis in this discussion:
OS X/MacOS has a concept for window layering that doesn't exist on X Window or in GTK (not explicitly, anyway).
Windows belong to a particular type layer. There is no way to make a window be above ALL other windows unless it is of the type that users the upper-most layer.
the current implementation of set_keep_above() (assuming it is like the one I originally worked on for GTK+2) only raises a window to the top of its layer group (just like the Cocoa equivalent).
If you want window to be "really on top", you have to ensure it will be on an upper layer, which in GTK terms means it needs to be a popup (for example).
The only thing that I have found to work is, sadly, an OS-specific fix, and one that cannot be done from C as far as I know.
The fix I propose is to add an Objective-C (e.g. foreground.m
) file to the project with the following contents:
#import <AppKit/AppKit.h>
void macos_force_foreground_level() {
[NSApp activateIgnoringOtherApps: YES];
}
You can then make this function available to the rest of your C program by also creating the following header file: (e.g. foreground.h
)
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void macos_force_foreground_level();
#ifdef __cplusplus
}
#endif
(The __cplusplus
stuff is for if you're actually also using this in a C++ program. If you're not, you can reduce the header file to just the #pragma once
line and the void macos_force_foreground_level();
line.)
Include the header file where you want to be able to present the main application window on the foreground; there you can then call macos_force_foreground_level()
to actually do it.
Of course, now you've added an Objective-C file to your project. On mac, you can compile this .m
file to a .o
file just using gcc
(which on Mac really is Apple's own version of clang
). (Make sure you're not passing flags like -std=c11
when compiling the .m
, since that file is not even C ;) ). For linking, make sure to add -framework Foundation -framework AppKit
to your linker flags.
If you have difficulties with making your build system work, you can ask in the comments, or ask another question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With