web-dev-qa-db-fra.com

Définition du titre de la fenêtre du terminal: wmctrl contre xdotool

Edit: Je ne cherche pas d'autres moyens ou de meilleurs moyens pour changer le titre d'une fenêtre ou pour ajouter des titres aux onglets des terminaux. Les réponses dans le doublon proposé ne sont en aucun cas près de résoudre le problème spécifique de savoir pourquoi xdotool search … ne récupère pas les titres des fenêtres lorsque le titre est défini par wmctrl comme décrit ci-dessus.


Système d'exploitation: Ubuntu 18.04

Lorsque j'ouvre une fenêtre gnome-terminal, le titre est dkb @ dkb: ~

Je peux le changer en utilisant

wmctrl -r :ACTIVE: -N "NewName"

mais xdotool search …, ne "voit" pas ce titre:

dkb@dkb:~$ xdotool search --name NewName
dkb@dkb:~$ 

Je récupère simplement l'invite au lieu de me fournir l'identifiant de fenêtre correspondant.

D'un autre côté, je peux utiliser xdotool lui-même pour définir le titre puis xdotool search … fournit l'identifiant de la fenêtre:

dkb@dkb:~$ xdotool getactivewindow set_window --name NewName
dkb@dkb:~$ xdotool search --name NewName
39845894
dkb@dkb:~$ 

En d'autres termes, si le titre est défini par xdotool, xdotool search fonctionne comme il se doit:

De man xdotool

modèle de recherche [options] Recherche des fenêtres avec des titres, des noms ou des classes avec un modèle d'expression régulière. Le résultat est une liste délimitée par des lignes d'identifiants X Window.

Donc, même si ce n'est pas un gros problème, je voudrais savoir pourquoi xdotool ne pas "voir" le titre de la fenêtre défini par wmctrl.

6
DK Bose

Nous pouvons voir qu'au moins xdotool getactivewindow getwindowname Fonctionne comme prévu.

$ wmctrl -r :ACTIVE: -N "Test1"
$ xdotool getactivewindow getwindowname
Test1
$ xdotool getactivewindow set_window --name Test2
$ xdotool getactivewindow getwindowname
Test2

Allons donc plus loin. Nous pouvons lister les propriétés de la fenêtre en utilisant la commande xprop -id <id>. Pour une fenêtre dont le nom est défini par wmctrl, cela donne:

_NET_WM_OPAQUE_REGION(CARDINAL) = 0, 0, 1920, 995
_NET_STARTUP_ID(UTF8_STRING) = "brisk-menu-2514-mariusz-HP-Pavilion-Notebook-mate-terminal-1_TIME1314631"
WM_WINDOW_ROLE(STRING) = "mate-terminal-window-4442-66103825-1563868224"
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL
_NET_WM_SYNC_REQUEST_COUNTER(CARDINAL) = 79691784, 79691785
_NET_WM_USER_TIME_WINDOW(WINDOW): window id # 0x4c00007
WM_CLIENT_LEADER(WINDOW): window id # 0x4c00001
_NET_WM_PID(CARDINAL) = 4442
WM_LOCALE_NAME(STRING) = "en_US.UTF-8"
WM_CLIENT_MACHINE(STRING) = "mariusz-HP-Pavilion-Notebook"
WM_NORMAL_HINTS(WM_SIZE_HINTS):
        program specified minimum size: 345 by 141
        program specified resize increment: 9 by 20
        program specified base size: 16 by 30
        window gravity: NorthWest
WM_PROTOCOLS(ATOM): protocols  WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING, _NET_WM_SYNC_REQUEST
WM_CLASS(STRING) = "mate-terminal", "Mate-terminal"
_NET_WM_ICON_NAME(UTF8_STRING) = "Terminal"
_NET_WM_NAME(UTF8_STRING) = "Test1"

Et pour une fenêtre dont le nom est défini par xdotool, cela donne:

_NET_WM_OPAQUE_REGION(CARDINAL) = 0, 0, 1920, 995
_NET_STARTUP_ID(UTF8_STRING) = "brisk-menu-2514-mariusz-HP-Pavilion-Notebook-mate-terminal-1_TIME1314631"
WM_WINDOW_ROLE(STRING) = "mate-terminal-window-4442-66103825-1563868224"
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL
_NET_WM_SYNC_REQUEST_COUNTER(CARDINAL) = 79691784, 79691785
_NET_WM_USER_TIME_WINDOW(WINDOW): window id # 0x4c00007
WM_CLIENT_LEADER(WINDOW): window id # 0x4c00001
_NET_WM_PID(CARDINAL) = 4442
WM_LOCALE_NAME(STRING) = "en_US.UTF-8"
WM_CLIENT_MACHINE(STRING) = "mariusz-HP-Pavilion-Notebook"
WM_NORMAL_HINTS(WM_SIZE_HINTS):
        program specified minimum size: 345 by 141
        program specified resize increment: 9 by 20
        program specified base size: 16 by 30
        window gravity: NorthWest
WM_PROTOCOLS(ATOM): protocols  WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING, _NET_WM_SYNC_REQUEST
WM_CLASS(STRING) = "mate-terminal", "Mate-terminal"
_NET_WM_ICON_NAME(UTF8_STRING) = "Terminal"
_NET_WM_NAME(STRING) = "Test2"

Et nous pouvons voir que dans les deux cas, _NET_WM_NAME Est correctement défini. Qu'est-ce que _NET_WM_NAME? C'est une extension pour x11 ( link , link )

_NET_WM_NAME

_NET_WM_NAME, UTF8_STRING

Le client DEVRAIT définir cela au titre de la fenêtre dans le codage UTF-8. S'il est défini, le gestionnaire de fenêtres doit l'utiliser de préférence à WM_NAME.

Les applications x11 devraient donc préférer cette propriété à WM_NAME. Voyons ces deux propriétés. J'ai pris le code C de ici :

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>

#define MAXSTR 1000

Display *display;
unsigned long window;
unsigned char *prop;

void check_status(int status, unsigned long window)
{
    if (status == BadWindow) {
        printf("window id # 0x%lx does not exists!", window);
        exit(1);
    }

    if (status != Success) {
        printf("XGetWindowProperty failed!");
        exit(2);
    }
}

unsigned char* get_string_property(char* property_name)
{
    Atom actual_type, filter_atom;
    int actual_format, status;
    unsigned long nitems, bytes_after;

    filter_atom = XInternAtom(display, property_name, True);
    status = XGetWindowProperty(display, window, filter_atom, 0, MAXSTR, False, AnyPropertyType,
                                &actual_type, &actual_format, &nitems, &bytes_after, &prop);
    check_status(status, window);
    return prop;
}

unsigned long get_long_property(char* property_name)
{
    get_string_property(property_name);
    unsigned long long_property = prop[0] + (prop[1]<<8) + (prop[2]<<16) + (prop[3]<<24);
    return long_property;
}

int main(int argc, char** argv)
{
    char *display_name = NULL;  // could be the value of $DISPLAY

    display = XOpenDisplay(display_name);
    if (display == NULL) {
        fprintf (stderr, "%s:  unable to open display '%s'\n", argv[0], XDisplayName (display_name));
    }
    int screen = XDefaultScreen(display);
    window = RootWindow(display, screen);

    window = get_long_property("_NET_ACTIVE_WINDOW");

    printf("_NET_WM_PID: %lu\n", get_long_property("_NET_WM_PID"));
    printf("WM_CLASS: %s\n", get_string_property("WM_CLASS"));
    printf("_NET_WM_NAME: %s\n", get_string_property("_NET_WM_NAME"));
    printf("WM_NAME: %s\n", get_string_property("WM_NAME"));

    XCloseDisplay(display);
    return 0;
}

Ajout d'une ligne printf("WM_NAME: %s\n", get_string_property("WM_NAME")); uniquement. Fonctionnement:

$ gcc test.c -o test -lX11
$ wmctrl -r :ACTIVE: -N "Test1"
$ ./test 
_NET_WM_PID: 4442
WM_CLASS: mate-terminal
_NET_WM_NAME: Test1
WM_NAME: (null)
$ xdotool getactivewindow set_window --name Test2
$ ./test 
_NET_WM_PID: 4442
WM_CLASS: mate-terminal
_NET_WM_NAME: Test2
WM_NAME: Test2

La conclusion est donc la suivante: xdotool définit à la fois _NET_WM_NAME Et WN_NAME Mais recherche uniquement par WM_NAME Et wmctrl définit uniquement _NET_WM_NAME.

5
Nykakin