Search code examples
c++clinuxuser-interfacegtkmm

Finding out the size of taskbar in Linux (C/C++/gtkmm/other)


How can I find the effective working are of my Linux desktop (by which I mean: screen's height - taskbar's height)?

I need this for my program, which I am writing in c++/gtkmm. I want to position the window in the bottom-right corner of the screen, above the taskbar.

At first I tried to maximize the window, check its height and subtract it from screen's height. For some reason it gives me the height before the maximalization, so it doesn't work.


Solution

  • You need to wait for the map-event event before checking the size of your window.

    Unlike what apmasell and senshikaze stated, you can quite reliably do this using GTK+. However, you should connect to the relevant signals (map-event, configure-event, screen-changed, visibility-notify-event and maybe window-state-event), so your small window will correctly move/resize, when screen resolution or toolbars change.

    For example, I personally use two auto-hidden bars on XFCE4. If there is a small tool window "docked" to the bottom right corner, I want it to move out of the way when my bottom bar is shown.

    If the window is a pure notification window, then I agree with apmasell that you're best off using libnotify (for example, run notify-send ... as a child process) to generate a normal notification window.

    As a proof of concept, here is a small C program, size.c, which obtains the information using a fully transparent undecorated window:

    #include <gtk/gtk.h>
    #include <gdk/gdk.h>
    #include <stdio.h>
    
    int screen_width = -1;
    int screen_height = -1;
    
    int window_left = -1;
    int window_top = -1;
    int window_width = -1;
    int window_height = -1;
    
    void done(GtkWidget *widget, void *payload)
    {
        GdkScreen *screen = gtk_widget_get_screen(widget);
    
        screen_width = gdk_screen_get_width(screen);
        screen_height = gdk_screen_get_height(screen);
    
        gtk_window_get_position((GtkWindow *)widget, &window_left, &window_top);
        gtk_window_get_size((GtkWindow *)widget, &window_width, &window_height);
    
        gtk_widget_destroy(widget);
        gtk_main_quit();
    }
    
    int main(int argc, char *argv[])
    {
        GtkWidget *window;
    
        gtk_init(&argc, &argv);
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_opacity((GtkWindow *)window, 0.0);
        gtk_window_set_decorated((GtkWindow *)window, (gboolean)FALSE);
        gtk_window_maximize((GtkWindow *)window);
        gtk_widget_show(window);
    
        g_signal_connect(window, "map-event", G_CALLBACK(done), NULL);
        gtk_main();
    
        if (screen_width > 0 && screen_height > 0)
            printf("Screen is %d x %d pixels\n", screen_width, screen_height);
    
        if (window_width > 0 && window_height > 0)
            printf("Window is %d x %d pixels\n", window_width, window_height);
    
        if (window_left > 0)
            printf("There is a %d pixel wide left bar\n", window_left);
    
        if (window_left >= 0 && window_width > 0 && screen_width > 0 && window_width + window_left < screen_width)
            printf("There is a %d pixel wide right bar\n", screen_width - (window_width + window_left));
    
        if (window_top > 0)
            printf("There is a %d pixel tall top bar\n", window_top);
    
        if (window_top >= 0 && window_height > 0 && screen_height > 0 && window_height + window_top < screen_height)
            printf("There is a %d pixel tall bottom bar\n", screen_height - (window_height + window_top));
    
        return 0;
    }
    

    Compile using

    gcc -W -Wall size.c `pkg-config --cflags --libs gtk+-3.0` -o size
    

    or, if still using GTK+ 2,

    gcc -W -Wall size.c `pkg-config --cflags --libs gtk+-2.0` -o size
    

    Run using ./size. Note that the test program only provides a snapshot; a real program should connect to the aforementioned signals to detect screen or toolbar changes, and update the window size/position accordingly.

    Hope you find this useful.