Russian Qt Forum
Сентябрь 30, 2024, 16:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Не ожидаемая передача фокуса  (Прочитано 4163 раз)
strelok_krr
Гость
« : Сентябрь 19, 2011, 16:48 »

Добрый день.
в первые пришлось столкнуться с Qt и Xlib.
Задача была такая - написать виртуальную клавиатуру для основного приложения (возможность использования точскрина) и оно должно быть постоянно в фокусе, т.е. при нажатии кнопки на виртуальной клавиатуре, фокус должен возвращаться назад.
реализовал это так:
Код:
//-------------------------------------------------------------------------------------------------------------------------------
void SendEvent(XKeyEvent *event, bool press)
{
if (press)
XSendEvent(event->display, event->window, True, KeyPressMask, (XEvent *)event);
else
XSendEvent(event->display, event->window, True, KeyReleaseMask, (XEvent *)event);
XSync(event->display, False);
XAllowEvents( event->display, ReplayKeyboard, CurrentTime);
XFlush( event->display );
}
//-------------------------------------------------------------------------------------------------------------------------------
void CWidget::btnClicked()
{
qDebug( "CWidget::btnClicked" );
Window win = *( m_curW->getLastWindow() );
XSetInputFocus( m_curW->getDisplay(), win, RevertToPointerRoot, CurrentTime );
XKeyEvent event;
event.display = m_curW->getDisplay();
event.window = win;
event.root = RootWindow(event.display, DefaultScreen(event.display));
event.subwindow = win;//None;
event.time = CurrentTime;
event.x = 1;
event.y = 1;
event.x_root = 1;
event.y_root = 1;
event.same_screen = True;
event.type = KeyPress;
event.state = 16;
event.keycode = XKeysymToKeycode(event.display, XStringToKeysym ("F6") );
SendEvent(&event, true);
event.type = KeyRelease;
SendEvent(&event, false);
}
проблема вот в чем. после передачи фокуса с клавиатуры, если в приложении отрыть и закрыть диалоговое окно, фокус возвращается не в "родительское" окно, а в клавиатуру.
Как это можно побороть?
заранее благодарен, за помощь.
Записан
strelok_krr
Гость
« Ответ #1 : Сентябрь 20, 2011, 17:56 »

В общем, пока сделал так: при старте виртуальной клавиатуры запоминаются все дескрипторы окон, также запоминается последние "чужие" окна. далее при получении фокуса на клавиатуру возвращаю фокус на последнее существующее окно из стека. решение кривое, но все же.
если, у кого есть другое решение, с удовольствием выслушаю.
Код:
void CCurrentWindow::findAllOurWindows( Window &window )
{
Window rootW, subwindow, *children;
unsigned int children_count;
XQueryTree( m_dsp, window, &rootW, &subwindow, &children, &children_count );

for( unsigned int i = 0; i < children_count; ++i ) {
m_ourW.push_back( children[i] );
findAllOurWindows( children[i] );
}
XFree( children );
}
//-------------------------------------------------------------------------------------------------------------------------------
void CCurrentWindow::loop()
{
if (m_dsp == NULL)
{
qDebug("ERROR! Couldn't connect to display %p.\n", m_dsp );
return ;
}
int revert_to;
*m_cur = DefaultRootWindow(m_dsp);
m_ourW.push_back( *m_cur );
findAllOurWindows( *m_cur );
*m_last = *m_cur;

unsigned int i, size = m_ourW.size();
qDebug( "count our windows=%d", size );
if ( 0 == size ) {
return;
}

const unsigned int stackOutWSize = 5;
m_stackOutW.push_back( DefaultRootWindow(m_dsp) );

Window tmp;
bool fFind = false;
bool fFirstOut = true;
do {
XGetInputFocus( m_dsp, &tmp, &revert_to );
if ( tmp <= 0 ) {
sleep(1);
continue;
}
for( i = 0; i < size; ++i ) {
if ( m_ourW[i] == tmp ) {
fFind = true;
*m_cur = tmp;
if ( !fFirstOut ) {
std::list<Window>::iterator it = m_stackOutW.end(), it_e = m_stackOutW.begin();
if ( it != it_e ) {
XWindowAttributes ret;
--it;
bool fFindWindow = false;
do {
if ( XGetWindowAttributes( m_dsp, *it, &ret ) && ( IsViewable == ret.map_state ) ) {
qDebug( "CCurrentWindow::loop Set out focus winId=%lu", *it );
fFindWindow = true;
break;
}
qDebug( "CCurrentWindow::loop Delete not used window %lu", *it );
m_stackOutW.erase( it );
--it;

} while ( it != it_e );
if ( fFindWindow ) {
XSetInputFocus( m_dsp, *it, RevertToPointerRoot, CurrentTime );
}
}
}
break;
}
}
if ( !fFind && ( *m_last != tmp ) ) {
*m_last = tmp;
fFirstOut = false;
if ( stackOutWSize < m_stackOutW.size() ) {
m_stackOutW.pop_front();
qDebug( "Delete old window" );
}
qDebug( "set new window focus [%lu]", tmp );
m_stackOutW.push_back( tmp );
}
fFind = false;

sleep(1);
} while( true );
}
//-------------------------------------------------------------------------------------------------------------------------------
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #2 : Сентябрь 20, 2011, 19:23 »

можно политику фокуса установить в "Нет фокуса" для клавиатуры
Записан

Юра.
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Сентябрь 20, 2011, 19:32 »

Цитировать
проблема вот в чем. после передачи фокуса с клавиатуры, если в приложении отрыть и закрыть диалоговое окно, фокус возвращается не в "родительское" окно, а в клавиатуру.
А кто является родителем диалога?
Записан

Qt 5.11/4.8.7 (X11/Win)
spirt
Гость
« Ответ #4 : Сентябрь 21, 2011, 11:25 »

А еще можно посмотреть QInputContext. И пример его использования: %QTDIR%/examples/tools/inputpanel
Записан
strelok_krr
Гость
« Ответ #5 : Сентябрь 21, 2011, 14:18 »

Цитировать
проблема вот в чем. после передачи фокуса с клавиатуры, если в приложении отрыть и закрыть диалоговое окно, фокус возвращается не в "родительское" окно, а в клавиатуру.
А кто является родителем диалога?
стороннее приложение для которого пишется клавиатура.
А еще можно посмотреть QInputContext. И пример его использования:  %QTDIR%/examples/tools/inputpanel
забыл уточнить, в разработке используется Qt3 Грустный
Записан
strelok_krr
Гость
« Ответ #6 : Сентябрь 21, 2011, 14:19 »

можно политику фокуса установить в "Нет фокуса" для клавиатуры
уточните, пожалуйста, не понял о чем идет речь.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.046 секунд. Запросов: 23.