LINUX.ORG.RU

Узнать имя окна в фокусе (текущего окна) через X11lib

 


0

1

Пытаюсь узнать имя текущего окна в фокусе пользователя. Когда запускаю программу в IDE, то в консоль выводится актуальное имя текущего окна, но когда переключаюсь на любое другое окно, в котором запущена другая программа, функция XFetchName() отрабатывает со статусом ошибки:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#include <X11/Xlib.h>
#include <X11/Xatom.h>
 
int main(int argc, char** argv)
{
 
    char* display_name = ":0";
    Display* display = XOpenDisplay(display_name);
 
    if (display == NULL) {
        fprintf(stderr, "Unable to open display '%s'\n", XDisplayName(display_name));
    }
 
    Window* win;
    int revert_to_return;
    char* name = NULL;
 
    while(1) {
        XGetInputFocus(display, win, &revert_to_return);
        if (XFetchName(display, *win, &name) > 0) {
            printf("%s\n", name);
        } else {
            printf("bad status\n");
        }
 
        XFree(name);
 
    }
 
    XCloseDisplay(display);
    return 0;
}


Почему так происходит? Возможно ли вообще получать имя окна в фокусе без сотен строчек кода?

P.S.: Вообще моя цель: достать текст, который выделяется двумя щелчками левой кнопки мышки, в произвольном текущем окне, где это возможно. Но я начал с освоения возможности поработать с текущим окном в фокусе.

1. Вместо указателя, указывающего в никуда, лучше написать так:

Window win;

XGetInputFocus(display, &win, &revert_to_return);

Дополнительно сравнивать возвращаемое значение c 0

if (XFetchName(display, win, &name) != 0) {

}

2. То что вы хотите сделать, ни коим образом не относится к selections. Посмотрите ICCCM (начальная точка: Глава 2).

uglym8 ()
Ответ на: комментарий от serg_orl

Вполне реально погуглить примеры.
Там ни разу не rocket science:)

Получили selection owner для интересующего вас selection, запросили форматы, в которых он может отдать содержимое selection'a.
Запросили данные в интересующем формате.

По идее с INCR вы не столкнетесь, хотя мне не известны размеры данных, которыми вы планируете оперировать.

Хотите получать информацию о смене selection owner - используйте XFixes.

Можно взглянуть на пример здесь на ЛОРе

Как вариант посмотреть на сорсы xclip.

P.S. XFetchName() теперь заработал?

uglym8 ()
Ответ на: комментарий от uglym8

uglym8, c учётом Ваших поправок:

void foo() {
    char* display_name = ":0";
    Display* display = XOpenDisplay(display_name);
 
    if (display == NULL) {
        fprintf(stderr, "Unable to open display '%s'\n", XDisplayName(display_name));
    }
 
    Window win;
    int revert_to_return;
    char* name = NULL;
 
    while(1) {
        XGetInputFocus(display, &win, &revert_to_return);
        if (XFetchName(display, win, &name) != 0) {
            printf("%s\n", name);
        } else {
            printf("bad status\n");
        }
 
        XFree(name);
 
    }
 
    XCloseDisplay(display);
}


В окне запуска: в выводе имею "FocusProxy"; а на остальных окнах также "bad status"
serg_orl ()
Ответ на: комментарий от serg_orl

УМВР

У меня подобное поведение возникает только в случае, если заголовок окна на кириллице.
По идее в этом случае надо использовать XGetWMName() и XmbTextPropertyToTextList()

   int count_return = 0;
   char **list = NULL;

.....

    if ((rv = XFetchName(display, win, &name)) != 0) {
          printf("%s\n", name);
      } else {
          printf("bad status. rv = 0x%x\n", rv);
  
          rv = XGetWMName(display, win, &text_prop);
          
          if (rv != 0) {
              printf("Got text property\n");
  
              res = XmbTextPropertyToTextList(display, &text_prop, &list, &count_return);
  
              /* TODO: Check res and count_return */
              printf("count_return = %d\n", count_return);
  
              printf("Title: %s\n", *list);
  
          } else {
              printf("bad status from XGetWMName(). rv = 0x%x\n", rv);
          }
      }


uglym8 ()
Ответ на: комментарий от uglym8

как подключить XTextProperty и XGetWMName? делаю:

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xresource.h>
но ловлю:

/main.cpp:28: ошибка: ‘XTextProperty’ was not declared in this scope
     XTextProperty txt;
     ^~~~~~~~~~~~~
main.cpp:28: suggested alternative: ‘XDeleteProperty’
     XTextProperty txt;
     ^~~~~~~~~~~~~
     XDeleteProperty

serg_orl ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.