URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9001
[ Назад ]

Исходное сообщение
"получить активное окно"

Отправлено Cupper , 19-Янв-11 15:47 
Здравствуйте. Задумал я в качестве самообучения написать корректор раскладки. Долго погуглив, составил примерный план дейтсвий

1. Вызов функции для определение активного окна (с фокусом ввода)
2. вызов gtk_window_get_focus () для получения виджета на котором фокус ввода
3. установка обработчика для события "focus-out-event", и обработчика для “key-press-event”

обработчик "focus-out-event"
    1.1. снимаем обработчик сигнала key-press-event и focus-out-event
    1.2. сбрасываем текущий буфер ввода
    1.3. возврат к п.1. поиска фокуса
обработчик “key-press-event”
    2.1. Если пробел, обнуляем буфер, выход
    2.2. Если символ, кладем в буфер новый символ, запускаем нити на поиск
    2.3. Иначе обнуляем буфер и выход

вот, но проблема возникает с самым первым этапом, получения дескриптора окна на которой сейчас фокус. Перерыл тонну сайтов, документацию по Gtk так и ненашел функции делающей это.

Но, нашел два других варианта, первый это Xlib:
XGetInputFocus(display, focus_return, revert_to_return)
    Display *display;
    Window *focus_return;
    int *revert_to_return;
вроде то что нужно, но как мне Window переделать в GtkWindow, ведь вся работа далее ведется именно с ним.

Второй способ, это делать связку функций
функция gtk_window_list_toplevels()
Цитата
Возвращает список всех существующих окон верхнего уровня. На виджеты в списке нет индивидуальных ссылок. Если вы хотите выполнить итерацию через список и выполнить действия, вовлекающие callbacks-функции, которые могли бы уничтожить виджеты, вы должны сначала вызвать g_list_foreach (result, (GFunc)g_object_ref, NULL), а затем убрать ссылки на все виджеты.

Далее перебирать весь список и проверять каждое окно функцией gtk_window_is_active ()
Цитата
Определяет, является ли окно частью текущего активного верхнего уровня. (Таким образом, окно верхнего уровня получает нажатие клавиши.) Значение TRUE возвращается, если активно непосредственно окно верхнего уровня, а так же если, скажем, GtkPlug встроен в активный верхний уровень. Вы можете использовать эту функцию, если хотите отрисовывать виджет по разному в активном и не активном окне. Смотрите gtk_window_has_toplevel_focus()

но тут я неуверн в том что правильно понял суть функций, и все же это мне кажеться плохое решение.

Подскажите что нибудь.


Содержание

Сообщения в этом обсуждении
"получить активное окно"
Отправлено pavlinux , 20-Янв-11 02:43 
> Здравствуйте. Задумал я в качестве самообучения написать корректор раскладки. Долго погуглив,
> составил примерный план действий
> 1. Вызов функции для определение активного окна (с фокусом ввода)


/*
* Возвращаем id окна где нажата кнопка, мышкобаттон или просто висит курсор,
* типа как в Жабескрипте - onFocus, onClick, onPress...
*
* $ gcc -lX11 xxx.c
* $ watch -n1 ./a.out
*
*/

#include <stdio.h> // printf
#include <X11/Xlib.h>

int main (void)
{
  XWindowAttributes attr;
  Window root, child, r, p, *kids;
  Display *dpy;  
  int rx, ry, wx, wy;
  unsigned int numkids, i, mapped, scrn, mask;

  dpy  = XOpenDisplay (0);
  scrn = DefaultScreen (dpy);

  XQueryPointer (dpy, RootWindow(dpy, scrn), &root, &child, &rx, &ry, &wx, &wy, &mask);
  mapped = 0;
  XQueryTree (dpy, root, &r, &p, &kids, &numkids);

  for (i = 0; i < numkids; ++i)
    {
     XGetWindowAttributes (dpy, kids[i], &attr);
        if (attr.map_state == IsViewable && child == kids[i]) {
                ++mapped;
                printf ("0x%lx\n", kids[i]);
        }
  }
return 0;
}

> Подскажите что нибудь.

http://tronche.com/gui/x/xlib/


"получить активное окно"
Отправлено Cupper , 20-Янв-11 09:44 
>> Здравствуйте. Задумал я в качестве самообучения написать корректор раскладки. Долго погуглив,
>> составил примерный план действий
>> 1. Вызов функции для определение активного окна (с фокусом ввода)
>> Подскажите что нибудь.
> http://tronche.com/gui/x/xlib/

хмм, а что же тогда делает функция XGetInputFocus ??? (http://tronche.com/gui/x/xlib/input/XGetInputFocus.html)


"получить активное окно"
Отправлено pavlinux , 20-Янв-11 15:01 
> хмм, а что же тогда делает функция XGetInputFocus ??? (http://tronche.com/gui/x/xlib/input/XGetInputFocus.html)

Надо вписать и проверить.
---


...
         ++mapped;
          printf ("Pointer: 0x%lx\n", kids[i]);
        }
    }
  XGetInputFocus(dpy, &focus_return, &revert_to_return);
  printf ("Focus: 0x%lx\n", focus_return);
  return 0;
}

Тоже чёй-то возвращает, тока числа разные :)

Pointer: 0xa00a3d
Focus: 0x280006f


"получить активное окно"
Отправлено Cupper , 20-Янв-11 15:26 
>[оверквотинг удален]
>         }
>     }
>   XGetInputFocus(dpy, &focus_return, &revert_to_return);
>   printf ("Focus: 0x%lx\n", focus_return);
>   return 0;
> }
>

> Тоже чёй-то возвращает, тока числа разные :)
> Pointer: 0xa00a3d
> Focus: 0x280006f

я вчера то же ее пробовал юзать, сделал это в цикле чтобы точно проверить, у меня определилось окно откротого QT creatora, но при переходе фокуса в любое другое окно независимо от того какое, было индетификатор какого то одного, так и не понял которого... вот и гадай блин, чего эта функция делает ((

Но даже если я заюзаю ваш вариант, и пускай он даже будет работать правильно, в итоге как мне полученный идентификатор окна переделать в дескриптор GtkWindow (к томуже мне это окно нужно приатачить к своему процесс что бы дальше с ним работать, я прав ?)


"получить активное окно"
Отправлено pavlinux , 20-Янв-11 15:30 
> я вчера то же ее пробовал юзать, сделал это в цикле чтобы
> точно проверить, у меня определилось окно откротого QT creatora, но при
> переходе фокуса в любое другое окно независимо от того какое, было
> индетификатор какого то одного,

Для XGetInputFocus() надо ещё нажать мышу или клаву :)


"получить активное окно"
Отправлено Cupper , 20-Янв-11 20:57 
>> я вчера то же ее пробовал юзать, сделал это в цикле чтобы
>> точно проверить, у меня определилось окно откротого QT creatora, но при
>> переходе фокуса в любое другое окно независимо от того какое, было
>> индетификатор какого то одного,
> Для XGetInputFocus() надо ещё нажать мышу или клаву :)

еще раз проверил работу, в итоге имею:
ваш код: отслеживает окно на который в данный момент наведен курсос (полезная штука, но не то)
мой код

void GetTopWindow1()
{
    Window winf;
    Display *dpy;
    dpy  = XOpenDisplay (0);
    int ret;
    if(dpy == NULL)
    {
        cout << "Не удалось соединится с X-Server" << endl;
        return;
    }
    //scrn = DefaultScreen (dpy);
    XGetInputFocus(dpy, &winf, &ret);
    printf ("0x%lx\n", winf);
    XCloseDisplay(dpy);
}

отслеживает окно по которому сделали целчек, или альтабов переключились, в общем сделали активным. Как раз почти то.

Теперь меня осинила одна классная идея. Мне совсем не нужно пытатся дескриптор Window преобразовать к GtkWindow. Напротив, мне нужно это окно (дескриптор которого я имею) приатачить (join) к своему процессу, и далее уже вступает Gtk-шная функция gtk_window_list_toplevels которая вернет мне все окна моего программы, надеюсь и то которое я ранее заджоинел, а среди них уже несложно найти то где фокус.

Новая проблема. Помню что гдето встречал функцию как приатачить чужое окно к своему процессу, но немогу найти... может кто вспомнит ?