2016-12-07 19 views
5

Według https://developer.gnome.org/gdk3/stable/GdkScreen.html#gdk-screen-get-active-window,'gdk_screen_get_active_window() jest przestarzała od wersji GTK + 3.22

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

Ale, co powinno być stosowane zamiast? (Jest to jedna z wielu przestarzałych funkcji GdkScreen.)

Aby określić konkretnie, w jaki sposób uzyskać położenie i geometrię aktywnego okna?

Edycja 12/10/16: Po kilku dniach sprawdzania tego, doszedłem do wniosku, że odpowiedź na to pytanie znajduje się poza developer.gnome.org. Być może oddzielny kod musi zostać napisany bezpośrednio na X11, Wayland i Mir.

Co jest warte, poniżej jest get_window-areas.c, które napisałem, badając, co można znaleźć w Gtk bez użycia przestarzałych funkcji. Wygląda na to, że nie ma sposobu na uzyskanie tytułów okien lub statusu aktywnego; tak, że nie mogłem powielić funkcji odpowiedzi @ theGtknerd, która używa niestabilnych bibliotek Wnck.

Po prostu uczę się Gtk, więc doceniam wszelkie uwagi do poprawy tego. Zacząłem od pustego kodu okna https://developer.gnome.org/gtk3/stable/gtk-getting-started.html#id-1.2.3.5, dodałem do niego widok tekstowy z buforem, a następnie wstawiłem informacje o geometrii i lokalizacji każdego okna do bufora tekstowego.

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

kompilacji get_window-areas.c poniżej polecenia gcc powyżej.

#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; 
} 
+0

Co próbujesz zrobić? Pobierz aktywne okno, aby móc je ustawić lub uzyskać nazwę okna? Myślę, że poprawny kod zależy od twoich potrzeb. – theGtknerd

+0

Chcę zrobić coś bardzo podobnego do tego, co robi screen-shooter xfce4, i tak analizowałem ich kod. Ta aplikacja służy do robienia zrzutów ekranu, a jedną z opcji jest uzyskanie obrazu aktywnego okna. Oczywiście do tej opcji użyto gdk_screen_get_active_window. To, czego oni (i ja) potrzebujemy, to lokalizacja i geometria okna. Zmienię moje pytanie na bardziej szczegółowe. –

Odpowiedz

2

(edycja 11.03.17 wyeliminować przecieki pamięci poprzez zamknięcie ekranu, gdy otwarty)

(edycja 6/03/17 do zainicjowania S w get_top_window)

(Edycja 12/24, uzyskując kompletna odpowiedź dla X11 i oznaczenie jako poprawnej odpowiedzi, dopóki ktoś nie ma ogólnego rozwiązania). Jest to część mojego w toku przepisywania/refaktoryzacji mojej aplikacji Silentcast (poprzednio tylko seria skryptów Bash używających Yada dla UI) na Githubie, chociaż jeszcze nie umieściłem żadnego z tego kodu Gtk na githubie.

Moja "poprawna odpowiedź" poniżej pozwala faktycznie uzyskać aktywny zakres GdkWindow, jego geometrię & lub aktywne okno X11 z dziećmi i jego geometrię.

Prawidłowe odpowiedzi

(zauważ, że to odnosi się tylko do X11 więc powinien zawierać i skompilować przeciwko gtk/gtkx.h nie gtk/gtk.h)

.h plików

/* 
* Filename: SC_X11_get_active_window.h 
* App Name: Silentcast <https://github.com/colinkeenan/silentcast> 
* Copyright © 2016, 2017 Colin N Keenan <[email protected]> 
* 
* 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); 

plik .c

/* 
* Filename: SC_X11_get_active_window.c 
* App Name: Silentcast <https://github.com/colinkeenan/silentcast> 
* Copyright © 2016 Colin N Keenan <[email protected]> 
* 
* 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 
} 

mojej poprzedniej odpowiedzi, które zwykle dostaje prawidłową geometrię, ale nie okno

Mam dostosowany kod z „get aktywne okno na X systemu okiennego” https://gist.github.com/kui/2622504 pracować z moim przykład w pytaniu. Zamieniłem go w bibliotekę. Nie zaznaczam tego jako poprawnej odpowiedzi, ponieważ jest to pierwszy plik biblioteki, jaki kiedykolwiek napisałem i jestem całkowicie nowy w Gtk. Nie mam też dużego doświadczenia w pisaniu kodu C. Na koniec poprawna odpowiedź powinna zawierać biblioteki dla X11, Wayland i MIR. Byłbym szczęśliwy widząc odpowiedź zawierającą moją bibliotekę z ulepszeniami + brakujące dwie biblioteki.

kompilacji poniżej:

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; 
} 
2

Oto kod Pythona, który pobiera aktywne okno i drukuje jego geometrię.

#!/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() 

Dokumentacja to https://developer.gnome.org/libwnck/stable/WnckWindow.html.

Edycja: Próbuję skompilować CI się z:

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

i pojawia się błąd:

/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" 

istnieje obejście, ale nie jestem pewien Wnck jest dobry zamiennik dla GdkScreen. Naprawdę nie wiem, co ci powiedzieć w tym momencie.

+0

Dzięki. Cieszę się, że znam tę bibliotekę, ale zgodnie z jej własną dokumentacją nie powinno się jej używać do tego, co robię, ponieważ "... korzystanie z tej biblioteki jest stosunkowo kosztowne pod względem zasobów." Cóż, dlatego od razu go zamknąłeś, ale czy nie ma sposobu, by to zrobić tylko z GdkScreen? https://developer.gnome.org/libwnck/stable/getting-started.html. Nie mogłem zrobić tego samego po prostu używając następnej funkcji po gdk_screen_get_active_window, np. Gdk-screen-get-window-stack: https://developer.gnome.org/gdk3/stable/GdkScreen.html#gdk-screen- get-window-stack –

+1

Ok, przyznaję, że nie programuję stosu Gtk, dlatego nie jestem autorytetem. Jednak myślę, że skoro robisz zrzut ekranu, używałbyś tych zasobów, a następnie ponownie je zwalniasz. Czy nie rozumiem tego poprawnie? Wydaje mi się, że GdkScreen musi mieć jakiś zamiennik (który jest tym, czego szukasz) i pasowałaby do niego libwnck. Powiem, że to dziwne, że Gdk nie podaje dokładnej funkcji, która zastępuje GdkScreen. Może to powinno być zgłoszone jako błąd https://bugzilla.gnome.org/ – theGtknerd

+0

Twoje rozwiązanie działa łatwo. Zaznaczę to jako zaakceptowaną odpowiedź, jeśli nikt nie zapewni niczego lepszego po kilku dniach. Czy możesz również opublikować wersję w C, ponieważ próbując nauczyć się Gtk, wszystkie odniesienia znajdują się w C.Kod, który modyfikuję, znajduje się w C. –

Powiązane problemy