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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: X11 window fullscreen  (Прочитано 12015 раз)
alexlogvinenkoit
Гость
« : Март 21, 2012, 13:24 »

Всем привет!

Подскажите, пожалуйста, как можно менять отображение X11 окна с оконного на полный экран и обратно при помощи X11 и/или OpenGL...

Спасибо!
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Март 21, 2012, 13:45 »

Код
C++ (Qt)
#include <X11/Xlib.h>
 
void showFullScreen( Display* dpy, Window wid )
{
XWindowAttributes xwa;
XGetWindowAttributes( dpy, wid, &xwa );
 
XEvent e;
e.xclient.type = ClientMessage;
e.xclient.message_type = XInternAtom( dpy, "_NET_WM_STATE", false );
e.xclient.display = dpy;
e.xclient.window = wid;
e.xclient.format = 32;
e.xclient.data.l[0] = 1;
e.xclient.data.l[1] = XInternAtom( dpy, "_NET_WM_STATE_FULLSCREEN", false );
e.xclient.data.l[2] = 0;
e.xclient.data.l[3] = 0;
e.xclient.data.l[4] = 0;
XSendEvent( dpy, xwa.root,
false, SubstructureNotifyMask | SubstructureRedirectMask, &e );
}
 
« Последнее редактирование: Март 21, 2012, 13:49 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
alexlogvinenkoit
Гость
« Ответ #2 : Март 21, 2012, 13:53 »

Непонятно почему, но не работает...

Код:

void MyClass::ToggleFullScreen()
{
        //переменная isFullScreen в классе, display и window тоже есть в классе
isFullScreen = !isFullScreen;

if(isFullScreen)
{
XWindowAttributes xwa;
XGetWindowAttributes(display, window, &xwa );

XEvent e;
e.xclient.type = ClientMessage;
e.xclient.message_type = XInternAtom( display, "_NET_WM_STATE", false );
e.xclient.display = display;
e.xclient.window = window;
e.xclient.format = 32;
e.xclient.data.l[0] = 1;
e.xclient.data.l[1] = XInternAtom( display, "_NET_WM_STATE_FULLSCREEN", false );
e.xclient.data.l[2] = 0;
e.xclient.data.l[3] = 0;
e.xclient.data.l[4] = 0;
XSendEvent( display, xwa.root,
false, SubstructureNotifyMask | SubstructureRedirectMask, &e );

XFlush(display);
}
}


Я уже натыкался на подобный пример, сделал тестовое приложение (без своих классов), так там работает...
Может дело в ООП? Хотя странно как-то...
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Март 21, 2012, 14:00 »

А какой стоит WM?
см. вывод
Код
Bash
xprop -root | grep _NET_SUPPORTED | grep _NET_WM_STATE_FULLSCREEN

Хотя, коли
Цитировать
сделал тестовое приложение (без своих классов), так там работает...
, то проблема где-то у тебя.
Смотри в отладчике window. Оно должно уже быть создано.
« Последнее редактирование: Март 21, 2012, 14:05 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
alexlogvinenkoit
Гость
« Ответ #4 : Март 21, 2012, 14:02 »

WM?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #5 : Март 21, 2012, 14:06 »

WM?
Window Manager
Записан

Qt 5.11/4.8.7 (X11/Win)
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #6 : Март 21, 2012, 14:09 »

Может дело в ООП? Хотя странно как-то...
И при чём здесь ООП Непонимающий
Вот рабочий код:
Код
C++ (Qt)
#include <QApplication>
#include <QLabel>
 
#include <X11/Xlib.h>
#include <QX11Info>
 
void showFullScreen( Display* dpy, Window wid )
{
XWindowAttributes xwa;
XGetWindowAttributes( dpy, wid, &xwa );
 
XEvent e = { 0 };
e.xclient.type = ClientMessage;
e.xclient.message_type = XInternAtom( dpy, "_NET_WM_STATE", false );
e.xclient.display = dpy;
e.xclient.window = wid;
e.xclient.format = 32;
e.xclient.data.l[0] = 1;
e.xclient.data.l[1] = XInternAtom( dpy, "_NET_WM_STATE_FULLSCREEN", false );
XSendEvent( dpy, xwa.root,
false, SubstructureNotifyMask | SubstructureRedirectMask, &e );
}
 
int main( int argc, char** argv )
{
QApplication app( argc, argv );
QLabel label( "Hello!" );
label.setAlignment( Qt::AlignCenter );
label.show();
 
showFullScreen( QX11Info::display(), label.winId() );
 
return app.exec();
}
 
Всё работает...
Записан

Qt 5.11/4.8.7 (X11/Win)
alexlogvinenkoit
Гость
« Ответ #7 : Март 21, 2012, 14:13 »

Я, наверное, понял в чем причина: у меня X11 окно - это Child другого X11 окна... В винде тоже такая проблема была, там решил функцией SetParent(HWND, HWND)... Здесь, наверное, так же сделаю...

P.S. Во всех примерах (что под Windows (WinAPI OpenGL/DirectX), что под Linux(X11 OpenGL) чтобы перейти из оконного режима в полноэкранный и наоборот - удаляют окно и строят его заново, при построении учитывая параметр fullscreen... Можно как-то без удаления окна обойтись?

Спасибо! Очень помог!
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #8 : Март 21, 2012, 14:18 »

у меня X11 окно - это Child другого X11 окна...
Ну дык, конечно, WM работает только с окнами созданными на root-window.

Цитировать
Можно как-то без удаления окна обойтись?
см. XReparentWindow()
« Последнее редактирование: Март 21, 2012, 14:21 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
alexlogvinenkoit
Гость
« Ответ #9 : Март 21, 2012, 14:48 »

Заработало!

Осталось только обратно в оконный режим перейти...

Спасибо огромное!
Записан
alexlogvinenkoit
Гость
« Ответ #10 : Март 27, 2012, 11:05 »

Еще раз здрасьте!

В продолжении вышесказанного возникла такая проблема: не могу выйти обратно в оконный режим, т.к. нет обработки событий... Итого окно разворачивается во весь экран, а чтобы выйти обратно в оконный - нужно нажать ALT+TAB и на родительском окне воспроизвести событие (у меня это нажатие клавиши клавиатуры)...

X11 окно - это parent от другого окна (GtkWidget)... Это обязательно для этой задачи.

В Windows была такая же проблема, но я просто подписался на WNDPROC и тогда все стало отрабатывать)

Вопрос на засыпку: как можно подписаться на какие-то асинхронные callback функции в X11? Или как-то по другому решить задачу...

Спасибо!
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #11 : Март 27, 2012, 11:14 »

Не уверен, но может поможет XSelectInput().
Давно уже на чистом XLib-e не писал.
Записан

Qt 5.11/4.8.7 (X11/Win)
alexlogvinenkoit
Гость
« Ответ #12 : Март 27, 2012, 11:34 »

GTK тоже ничего, но OpenGL не поддерживает... Есть GTKGLEXT, который поддерживает, но возникает баг, не хочет инициализироваться GLEW, а он нужен, т.к. в программе используется шейдер... Да и вообще протестил обычный OpenGL через X11 и через GTKGLEXT - небо и земля... X11 быстро отрабатывает, а GTKGLEXT глючит и проц жрет.

И никак нельзя объявить mainloop для X11, т.к. есть mainloop в GTK...

Читал про 2 способа: XSelectInput и XGrabPointer/XGrabKeyboard...

Но что находил в примерах - все равно объявлен mainloop x11...
Идеальный вариант - подписаться на событие (может GTK или GDK событие, там же есть асинхронные CALLBACK-и)...
Записан
alexlogvinenkoit
Гость
« Ответ #13 : Март 30, 2012, 10:07 »

Описал проблему на stackowerflow, есть интересный ответ... Предложили мне 2 выхода:

Цитировать
Well, you needs some sort of event pump, and being a child window on a shared X display connection means, it's tethered to the main event loop. Technically you could start a second thread with its own display connection and event loop. Unfortunately Xlib is not very thread safe, especially in that regard. You could do it with Xcb.

Another approach would be putting the child under custody of a separate process and use XEmbed.

Короче можно либо обработку событий пускать в отдельный поток, однако Xlib очень потоконебезобасен, либо использовать Xcb... Насчет первого - я практически уверен, что не заработает... Насчет второго - пока что не знаю, попробую, отпишу)
Записан
alexlogvinenkoit
Гость
« Ответ #14 : Апрель 05, 2012, 18:40 »

Да, без mail-лупа не обойтись никак... Пока что настроил поток, и мьютексами лочу, делаю что мне надо, а потом разлачиваю... Т.е. лок - получить событие - анлок - если событие = кнопка отпущена - лок - в полноэкранный/оконный режим - анлок... Геморно, но работает... Единственное но - это то, что 1 раз отрабатывает, на 2-й уже долго тупит и отрабатывает...
В Windows эта же процедура занимает очень мало времени, хотя и там и тут идет ReparentWindow (без пересоздавания окна).

На IRC-е описал проблему в канале XCB, там мне сказали только такое: "Да, используя XCB, можно обойтись без mainloop-а, и все будет работать". Больше ничего. А в примерах и туториалах самого XCB - объявлен mainloop.
Еще вариант XEmbed, но тоже ни на что не наткнулся, что хоть как-то затрагивало бы проблему...

Есть хоть какие-то идеи?

Спасибо!
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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