7

According to https://developer.gnome.org/gdk3/stable/GdkScreen.html#gdk-screen-get-active-window,

gdk_screen_get_active_window has been deprecated since version 3.22 and should not be used in newly-written code.

But, what should be used instead? (This is one of many deprecated GdkScreen functions.)

To be specific, how would I obtain the location and geometry of the active window?

Edit 12/10/16: After a couple of days looking into this, I've come to the conclusion the answer to this question is outside developer.gnome.org. It may be that separate code needs to be written directly targeting X11, wayland, and mir.

For what it's worth, below is get_window-areas.c that I have written exploring what can be found in Gtk without using deprecated functions. It seems there isn't a way to get window titles or active status; so that, I could not duplicate the functionality of @theGtknerd's answer which uses unstable Wnck libraries.

I am just learning Gtk, so I do appreciate any comments for improving this. I started with the empty window code https://developer.gnome.org/gtk3/stable/gtk-getting-started.html#id-1.2.3.5, added a textview with buffer to it, and then inserted information about the geometry and location of each window into the text buffer.

gcc `pkg-config --cflags gtk+-3.0` -o get_window-areas get_window-areas.c `pkg-config --libs gtk+-3.0`

Compile get_window-areas.c below with the gcc command above.

#include <gtk/gtk.h>

static void
activate (GtkApplication* app,
          gpointer        user_data)
{
  GtkWidget *window = NULL;
  GtkWidget *text_view;
  GtkTextBuffer *buffer;
  int x = 0, y = 0, width = 0, height = 0;
  char char_x[5], char_y[5], char_width[5], char_height[5];
  GdkScreen *screen;
  GdkWindow *dwindow;
  GList *gl_item = NULL, *gl = NULL;

  window = gtk_application_window_new (app);
  screen = gtk_window_get_screen (GTK_WINDOW(window));
  buffer = gtk_text_buffer_new (NULL);
  text_view = gtk_text_view_new_with_buffer (buffer);
  gtk_container_add (GTK_CONTAINER (window), text_view);

  if(screen != NULL)
    { 
      gl = gdk_screen_get_window_stack(screen);
      for (gl_item = g_list_first(gl); gl_item != NULL; gl_item = gl_item->next) 
      { 
        dwindow=gl_item->data;
        gdk_window_get_root_origin(dwindow, &x, &y);
        width = gdk_window_get_width(dwindow);
        height = gdk_window_get_height(dwindow);
        g_object_unref(dwindow);
        snprintf (char_x, 5, "%d", x);
        snprintf (char_y, 5, "%d", y);
        snprintf (char_width, 5, "%d", width);
        snprintf (char_height, 5, "%d", height);
        gtk_text_buffer_insert_at_cursor(buffer,char_width,-1);
        gtk_text_buffer_insert_at_cursor(buffer,"x", -1);
        gtk_text_buffer_insert_at_cursor(buffer,char_height,-1);
        gtk_text_buffer_insert_at_cursor(buffer," at (", -1);
        gtk_text_buffer_insert_at_cursor(buffer,char_x, -1);
        gtk_text_buffer_insert_at_cursor(buffer,",", -1);
        gtk_text_buffer_insert_at_cursor(buffer,char_y,-1);
        gtk_text_buffer_insert_at_cursor(buffer,")\n", -1);
      }; 
      g_list_free (gl);
    } 
  else {gtk_text_buffer_insert_at_cursor(buffer, "Failed to get default screen.\n", -1);}

  gtk_widget_show_all (window);
}

int
main (int    argc,
      char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new ("com.github.colinkeenan.silentcast", 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;
}
Colin Keenan
  • 1,089
  • 12
  • 20
  • What are you trying to do? Get the active window so you can focus it or get the name of the window? I think the correct code depends on your need. – theGtknerd Dec 07 '16 at 22:58
  • I want to do something very similar to what xfce4-screenshooter does, and so was examining their code. That application is for taking screenshots, and one option is to get a picture of the active window. Of course, gdk_screen_get_active_window is used for that option. What they (and I) need is the location and geometry of the window. I will edit my question to be more specific. – Colin Keenan Dec 08 '16 at 17:28

2 Answers2

4

Here is Python code that gets the active window and prints its geometry.

#!/usr/bin/python

import gi
gi.require_version('Wnck', '3.0')
from gi.repository import Wnck
screen = Wnck.Screen.get_default()
screen.force_update()  # recommended per Wnck documentation

# loop all windows
for window in screen.get_windows():
   if window.is_active() == True:
        print (window.get_geometry())
        window_name = window.get_name()
        print (window_name)

# clean up Wnck (saves resources, check documentation)
window = None
screen = None
Wnck.shutdown()

The documentation is https://developer.gnome.org/libwnck/stable/WnckWindow.html.

Edit: I am trying to compile the C I have with:

gcc `pkg-config --cflags --libs libwnck-3.0` -o wnck wnck.c

and I get the error:

/usr/include/libwnck-3.0/libwnck/window.h:30:2: error: #error "libwnck should only be used if you understand that it's subject to frequent change, and is not supported as a fixed API/ABI or as part of the platform"

there is a workaround, but I am not sure Wnck is a good replacement for GdkScreen. I really do not know what to tell you at this point.

theGtknerd
  • 3,647
  • 1
  • 13
  • 34
  • Thanks. I'm glad to know about this library, but according to it's own documentation, it shouldn't be used for what I'm doing because ". . . the use of this library is relatively expensive in terms of resources." Well, that's why you shut it down right away, but isn't there a way to do this with just GdkScreen? https://developer.gnome.org/libwnck/stable/getting-started.html. Couldn't I do the same thing just using the very next function after gdk_screen_get_active_window, i.e. gdk-screen-get-window-stack: https://developer.gnome.org/gdk3/stable/GdkScreen.html#gdk-screen-get-window-stack – Colin Keenan Dec 08 '16 at 23:48
  • 1
    Ok, I admit I do not program the Gtk stack, therefore I am not the authority. However, I would think since you are taking a screenshot, you would use these resources and then free them up again. Am I not understanding this correctly? It seems to me GdkScreen must have some replacement (which is what you are looking for) and libwnck would fit. I will say it is weird that Gdk does not list the exact function that replaces GdkScreen. Maybe this should be filed as a bug https://bugzilla.gnome.org/ – theGtknerd Dec 09 '16 at 03:46
  • Your solution works easily. I will mark it as the accepted answer if nobody provides anything better after a couple of days. Can you also post a version in C because in trying to learn Gtk, the references are all in C. Also, the code I'm modifying is in C. – Colin Keenan Dec 09 '16 at 04:30
  • 1
    Let me see what I can do. My C is rusty and needs some grease :-( It will be a couple days as I have other commitments too. – theGtknerd Dec 09 '16 at 11:24
  • 1
    I have edited my answer with the warning Wnck in C generates. I think I would file a bug on bugzilla about GdkScreen not having a replacement if I were you. – theGtknerd Dec 10 '16 at 00:57
  • 1
    Thanks. I will file that bug in the next couple of days. I have been trying to do what you did, but with Gtk. It's slow going though since I don't know Gtk at all and it's been over 25 years since I programmed in C. Some of my biggest problems are with casting/pointers/snprintf..., but I think I've got it now. – Colin Keenan Dec 10 '16 at 06:13
  • Another thing of interest is https://blog.gtk.org/2016/10/24/this-week-in-gtk-21/ Quote: `various GdkScreen API — replaced by GdkMonitor` However, GdkMonitor does not have a `get_active_window` :( – theGtknerd Dec 10 '16 at 13:35
  • I've decided not to file a bug because it looks to me that they don't plan on having a replacement for this. They are getting rid of any X11 specific stuff. Also, Gtk is for building a GUI application, not for getting details about other applications that may not be Gtk. Seems the answer to this question is outside developer.gnome.org. – Colin Keenan Dec 10 '16 at 22:48
  • You know, I never gave that a thought. With news that X11 is going to be replaced, it might make it the reason that they are dropping the `get_active_window` Hint: if you google some of the Wnck code I have posted you will find interesting topics out there about Wnck. – theGtknerd Dec 10 '16 at 23:00
3

(edit 3/11/17 to eliminate memory leaks by closing display whenever opened)

(edit 3/6/17 to initialize s in get_top_window)

(edit 12/24 to provide a complete answer for X11, and marking as correct answer until somebody has a general solution). It is part of my in progress rewriting/refactoring of my silentcast application (previously just a series of bash scripts using yad for the UI) on github, although I have not yet put any of this Gtk code on github.

My "Correct Answer" below allows you to actually get the active GdkWindow, it's geometry & extents, or the active X11 window with children, and it's geometry.

Correct Answer

(note that it only applies to X11 so should include and compile against gtk/gtkx.h, not gtk/gtk.h)

.h file

/*
 *  Filename: SC_X11_get_active_window.h 
 *  App Name: Silentcast <https://github.com/colinkeenan/silentcast>
 *  Copyright © 2016, 2017 Colin N Keenan <colinnkeenan@gmail.com>
 * 
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see <http://www.gnu.org/licenses/>.
 * 
 *  Description: defines some custom X11 error messags and exposes 3 functions:
 *  SC_get_active_gdkwindow (...), SC_get_geomeotry_for (...), 
 *  and SC_get_active_windows_and_geometry (...)
 */

#include <gtk/gtkx.h>

#define SC_X11_ERROR0 "                                      \n"
#define SC_X11_ERROR1 "Failed to connect to X server.\n"
#define SC_X11_ERROR2 "x11 error trying to get focused window\n"
#define SC_X11_ERROR3 "X11 reports no focused window\n"
#define SC_X11_ERROR4 "X11 error trying to get top window\n"

#define D_ERR 1
#define FOCUS_ERR1 2
#define FOCUS_ERR2 3
#define TOP_ERR 4
#define UKN_ERR 5

#define SC_X11_E1 D_ERR
#define SC_X11_E2 FOCUS_ERR1
#define SC_X11_E3 FOCUS_ERR2
#define SC_X11_E4 TOP_ERR
#define SC_X11_E0 UKN_ERR

unsigned int SC_get_active_X11window (Window *w, Window* *w_children, ssize_t *n);

gboolean SC_get_active_gdkwindow (Window aw, Window *aw_children, ssize_t n, GdkWindow* *gdkwindow);

void SC_get_geometry_for (Window aw, Window *aw_children, ssize_t n, int *x, int *y, 
        unsigned int *width, unsigned int *height, GdkRectangle *extents, GdkWindow* *gdkwindow); 

gboolean SC_get_active_windows_and_geometry (Window *aw, Window* *aw_children, ssize_t *n,
        int *x, int *y, unsigned int *width, unsigned int *height, GdkRectangle *extents, GdkWindow* *gdkwindow); 

.c file

/*
 *  Filename: SC_X11_get_active_window.c 
 *  App Name: Silentcast <https://github.com/colinkeenan/silentcast>
 *  Copyright © 2016 Colin N Keenan <colinnkeenan@gmail.com>
 * 
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see <http://www.gnu.org/licenses/>.
 * 
 *  Description: adapted from "get the active window on X window system" 
 *               https://gist.github.com/kui/2622504
 *               to get Gdk geometry of the active window, both the
 *               inner window and the extents
 */


#include "SC_X11_get_active_window.h"

Bool xerror = False;

static int handle_error (Display* display, XErrorEvent* error) {
  xerror = True;
  return 1;
}

static int get_focus_window (Display* d, Window *w) {
  int revert_to;

  XGetInputFocus (d, w, &revert_to);
  if (xerror) return FOCUS_ERR1; //X error trying to get focused window
  else if (w == None) return FOCUS_ERR2; //no focused window
  else return 0;
}

static int get_top_window (Display* d, Window start, Window *w, Window* *w_children, ssize_t *n) {
  Window parent = start, root = None, *children = NULL;
  *w = start; 
  unsigned int nchildren;
  Status s = XQueryTree (d, *w, &root, &parent, &children, &nchildren), s_prev;

  /* ultimately trying to get *w and *w_children */
  while (parent != root && !xerror) {

    *w = parent; //previous parent
    s_prev = s; //previous status of XQueryTree
    if (s_prev) {
      *w_children = children; //previous children
      *n = nchildren; //previous number of children
    }

    s = XQueryTree (d, *w, &root, &parent, &children, &nchildren);
    /* When parent == root, the previous "parent" is the top window.
     * Save the children of the top window too, but XFree all other
     * children.
     */
    if (parent != root) {
    // parent is not root, so previous parent wasn't top window, so don't need it's children
      if (s_prev) XFree (*w_children); 
    } else 
      if (s) XFree (children); // don't keep the children of root either
  }
  if (xerror) return TOP_ERR;
  else return 0;
}

unsigned int 
SC_get_active_X11window (Window *w, Window* *w_children, ssize_t *n)
{
  Display* d = NULL;
  unsigned int e = 0;

  XSetErrorHandler (handle_error);
  d = XOpenDisplay (NULL); 
  if (d == NULL) { 
    return D_ERR; 
  } else {
    /* set w to the focused window */
    e = get_focus_window (d, w); 
    if (e) { //if error
      XCloseDisplay (d);
      return e;
    }
    /* get_top_window will set w to the top focused window (active window) */
    e = get_top_window (d, *w, w, w_children, n); 
    if (e) { //if error
      XCloseDisplay (d);
      return e;
    }
    XCloseDisplay(d);
  } 

  return 0; //no error
}

/* SC_get_active_gdkwindow (...) tries to match a GdkWindow to one of the passed X11
 * windows (supposed to be the active X11 window and it's n children), and returns
 * TRUE if such a match is found, FALSE if not
 */
gboolean
SC_get_active_gdkwindow (Window aw, Window *aw_children, ssize_t n, GdkWindow* *gdkwindow) {
  ssize_t i = 0;
  GdkWindow *dwindow = NULL;
  GdkScreen *screen = NULL;
  GList *gl_item = NULL, *gl = NULL;
  gboolean active_window_found = FALSE;


  screen = gdk_screen_get_default ();
  if (screen != NULL) { 
    /* Go through all windows known to Gtk and check XID against active X11 window, aw. */
    gl = gdk_screen_get_window_stack (screen);
    for (gl_item = g_list_first (gl); !active_window_found && gl_item != NULL; gl_item = gl_item->next) { 

      dwindow = gl_item->data;

      if (gdk_x11_window_get_xid (dwindow) == aw) active_window_found = TRUE;
      else for (i = 0; i < n; i++)  //aw didn't match this dwindow, so check all of aw_children
        if (gdk_x11_window_get_xid (dwindow) == aw_children[i]) active_window_found = TRUE;

      if (!active_window_found) g_object_unref (dwindow);
      else *gdkwindow = dwindow;
    } 
    g_list_free (gl);
  }
  return active_window_found;
}

/* SC_get_geometry_for (...) trys to get the Gdk geometry for the GdkWindow
 * matching the passed X11 window with children, getting both the internal
 * window geometry and it's extents (title-bar/frame). If can't get Gdk info
 * will get the X11 geometry, setting both inner and extents geometry to
 * the same values. 
 */

void
SC_get_geometry_for (Window aw, Window *aw_children, ssize_t n, GdkRectangle *win_rect, GdkRectangle *extents, GdkWindow* *dwindow) {
  unsigned int bwidth = 0, depth = 0, width, height;
  int x, y;
  Window root = 0;

  if (SC_get_active_gdkwindow (aw, aw_children, n, dwindow)) {
    gdk_window_get_frame_extents (*dwindow, extents); //{top-left corner, width & height} of title-bar/borders
    gdk_window_get_origin(*dwindow, &x, &y); //top-left corner of interior window (not title bar/borders)
    width = gdk_window_get_width (*dwindow); //width of interior window
    height = gdk_window_get_height (*dwindow); //height of interior window
    win_rect->x = x;
    win_rect->y = y;
    win_rect->width = (int) width;
    win_rect->height = (int) height;
  } else {
    fprintf (stderr, "Failed to get GdkWindow. Falling back on X11 geometry of active window, saved as both extents and interior geometry.");
    Display* d = XOpenDisplay (NULL); 
    if (d) {
      XGetGeometry (d, aw, &root, &x, &y, &width, &height, &bwidth, &depth);
      XCloseDisplay (d);
      extents->x = x;
      extents->y = y;
      extents->width = (int) width;
      extents->height = (int) height;
    }
  }
}

/* SC_get_active_windows_and_geometry (...) calls get_active_x11window (...) to get the active X11 window
 * and it's children, then calls SC_get_geometry_for (...) to get geometry (hopefully Gdk) that matches
 */
gboolean
SC_get_active_windows_and_geometry (Window *aw, Window* *aw_children, ssize_t *n, 
    GdkRectangle *win_rect, GdkRectangle *extents, GdkWindow* *dwindow) {

  switch (SC_get_active_X11window(aw, aw_children, n)) {  get aw, aw_children, and n (number of children)
case 0: SC_get_geometry_for (*aw, *aw_children, *n, win_rect, extents, dwindow); return TRUE; 
case SC_X11_E1: fprintf (stderr, SC_X11_ERROR1); break;
case SC_X11_E2: fprintf (stderr, SC_X11_ERROR2); break;
case SC_X11_E3: fprintf (stderr, SC_X11_ERROR3); break;
case SC_X11_E4: fprintf (stderr, SC_X11_ERROR4); break;
  }     
  return FALSE; //failed to get active window due to X11 error
}

My Previous answer that usually got correct geometry, but not the window

I have adapted code from "get the active window on X window system" https://gist.github.com/kui/2622504 to work with my example in the question. I turned it into a library. I'm not marking this as the correct answer because this is the first library file I've ever written and I'm completely new to Gtk as well. I also don't have much experience writing C code. Finally, the correct answer should include libraries for X11, Wayland, and MIR. I would be happy to see an answer including my library with improvements + the missing two libraries.

Compile below with:

gcc `pkg-config --cflags gtk+-3.0` -o get_window-areas X11_get_active_window_geometry.c get_window-areas.c `pkg-config --libs gtk+-3.0` -lX11

X11_get_active_window_geometry.h

#include <X11/Xlib.h>

#define SC_X11_ERROR0 "Uknown error from get_actve_window_geometry.\n"
#define SC_X11_ERROR1 "Failed to connect to X server.\n"
#define SC_X11_ERROR2 "x11 error trying to get focused window\n"
#define SC_X11_ERROR3 "X11 reports no focused window\n"
#define SC_X11_ERROR4 "X11 error trying to get top window\n"
#define SC_X11_ERROR5 "X11 error trying to get the active-window geometry.\n"

#define D_ERR 1
#define FOCUS_ERR1 2
#define FOCUS_ERR2 3
#define TOP_ERR 4
#define GEOM_ERR 5

#define SC_X11_E1 D_ERR
#define SC_X11_E2 FOCUS_ERR1
#define SC_X11_E3 FOCUS_ERR2
#define SC_X11_E4 TOP_ERR
#define SC_X11_E5 GEOM_ERR

unsigned int get_active_window_geometry (int *x, int *y, unsigned int *width, unsigned int *height); 

X11_get_active_window_geometry.c

#include "X11_get_active_window_geometry.h"

Bool xerror = False;

static int handle_error (Display* display, XErrorEvent* error) {
  xerror = True;
  return 1;
}

static int get_focus_window (Display* d, Window *w) {
  int revert_to;

  XGetInputFocus (d, w, &revert_to);
    if (xerror) return FOCUS_ERR1; //X error trying to get focused window
    else if (w == None) return FOCUS_ERR2; //no focused window
    else return 0;
}

static int get_top_window (Display* d, Window start, Window *w){
    Window parent = start, root = None, *children;
  *w = start; 
  unsigned int nchildren;
  Status s;

  while (parent != root && !xerror) {
    *w = parent;
    s = XQueryTree (d, *w, &root, &parent, &children, &nchildren);

    if (s)
      XFree (children);
  }
    if (xerror) return TOP_ERR;
    else return 0;
}

unsigned int get_active_window_geometry (int *x, int *y, 
        unsigned int *width, unsigned int *height) 
{
    Display* d = NULL;
    Window root, w;
  unsigned int bwidth = 0, depth = 0, e = 0;

  XSetErrorHandler (handle_error);
  d = XOpenDisplay (NULL);
    if (d == NULL) { 
        return D_ERR;   
    } else {
        e = get_focus_window (d,&w); //get focused window w
        if (e) return e;
    e = get_top_window (d, w, &w); //get top focused window w (the active window)
        if (e) return e;
        XGetGeometry (d, w, &root, x, y, width, height, &bwidth, &depth);
        if (xerror) return GEOM_ERR;
    } 
    return 0;
}

get_active_window.c

#include <gtk/gtk.h>
#include "X11_get_active_window_geometry.h"

static void
activate (GtkApplication* app,
          gpointer        user_data)
{
  GtkWidget *window = NULL, *text_view;
  GtkTextBuffer *buffer;
    unsigned int width = 0, height = 0, widtha = 0, heighta = 0, iwidtha = 0, iheighta = 0;
    int x = 0, y = 0, xa = 0, ya = 0, ixa =0, iya = 0;
  GdkRectangle extents= { 0, 0, 0, 0 };
    char char_x[5], char_y[5], char_width[5], char_height[5]; 
    GdkScreen *screen;
    GdkWindow *dwindow;
    GList *gl_item = NULL, *gl = NULL;

  window = gtk_application_window_new (app);
    screen = gtk_window_get_screen (GTK_WINDOW(window));
  buffer = gtk_text_buffer_new (NULL);
  text_view = gtk_text_view_new_with_buffer (buffer);
  gtk_container_add (GTK_CONTAINER (window), text_view);

#define ADD_TEXT(STRING) gtk_text_buffer_insert_at_cursor (buffer,STRING,-1)
#define ADD_INT(CHAR_INT,INT) snprintf (CHAR_INT, 5, "%d", INT); ADD_TEXT(CHAR_INT);
#define ADD_GEOMETRY_TEXT(X,Y,WIDTH,HEIGHT) ADD_INT(char_width, WIDTH); ADD_TEXT("x"); ADD_INT(char_height, HEIGHT); ADD_TEXT(" at ("); ADD_INT(char_x, X); ADD_TEXT(","); ADD_INT(char_y, Y); ADD_TEXT(")\n");

    /* get active window geometry using X11 and handle error, if any*/
    switch (get_active_window_geometry(&xa, &ya, &widtha, &heighta)) { 
case 0:
            ADD_TEXT("GEOMETRY FOR ACTIVE WINDOW USING X11\n");
            ADD_GEOMETRY_TEXT(xa, ya, widtha, heighta);
            ADD_TEXT("\n");
            break;
case SC_X11_E1:
            ADD_TEXT(SC_X11_ERROR1);
            break;
case SC_X11_E2:
            ADD_TEXT(SC_X11_ERROR2);
            break;
case SC_X11_E3:
            ADD_TEXT(SC_X11_ERROR3);
            break;
case SC_X11_E4:
            ADD_TEXT(SC_X11_ERROR4);
            break;
case SC_X11_E5:
            ADD_TEXT(SC_X11_ERROR5);
            break;
default:
            ADD_TEXT(SC_X11_ERROR0);
    }           

    /* get window geometry for all windows using Gtk and identify the active one by comparison with X11 result*/
    if (screen != NULL) { 
        ADD_TEXT("GEOMETRY FOR ALL WINDOWS USING Gtk:\n\n");
        gl = gdk_screen_get_window_stack (screen);
        for (gl_item = g_list_first (gl); gl_item != NULL; gl_item = gl_item->next) { 
            dwindow=gl_item->data;
      gdk_window_get_frame_extents (dwindow, &extents); //{top-left corner, width & height} of title-bar/borders
            ADD_TEXT("Entirety of Window: ");
            ADD_GEOMETRY_TEXT(extents.x, extents.y, extents.width, extents.height);
            gdk_window_get_origin(dwindow, &x, &y); //top-left corner of interior window (not title bar/borders)
            width = gdk_window_get_width (dwindow); //width of interior window
            height = gdk_window_get_height (dwindow); //height of interior window
            ADD_TEXT("Interior of Window: ");
            ADD_GEOMETRY_TEXT(x, y, width, height);
            ADD_TEXT("\n");
            /*If extents matches active window geometry, save interior window geometry */
            if (extents.x == xa && extents.y == ya && extents.width == widtha && extents.height == heighta) {
                ixa = x; iya = y; iwidtha = width; iheighta = height;
            }
            g_object_unref (dwindow);
        }; 
        g_list_free (gl);
        ADD_TEXT("MATCHING THE ACTIVE WINDOW REPORTED BY X11 WITH THE GTK WINDOW GEOMETRIES:\n");
        ADD_TEXT("Entirety of Active Window: ");
        ADD_GEOMETRY_TEXT(xa, ya, widtha, heighta);
        ADD_TEXT("Interior of Active Window: ");
        ADD_GEOMETRY_TEXT(ixa, iya, iwidtha, iheighta);
    } else {
        ADD_TEXT("Failed to get default screen.\n");
    }

  gtk_widget_show_all (window);
}

int
main (int    argc,
      char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new ("com.github.colinkeenan.silentcast", 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;
}
Colin Keenan
  • 1,089
  • 12
  • 20