Russian Qt Forum

Компиляторы и платформы => Linux => Тема начата: alexlogvinenkoit от Март 21, 2012, 13:24



Название: X11 window fullscreen
Отправлено: alexlogvinenkoit от Март 21, 2012, 13:24
Всем привет!

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

Спасибо!


Название: Re: X11 window fullscreen
Отправлено: GreatSnake от Март 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 );
}
 


Название: Re: X11 window fullscreen
Отправлено: alexlogvinenkoit от Март 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);
}
}


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


Название: Re: X11 window fullscreen
Отправлено: GreatSnake от Март 21, 2012, 14:00
А какой стоит WM?
см. вывод
Код
Bash
xprop -root | grep _NET_SUPPORTED | grep _NET_WM_STATE_FULLSCREEN

Хотя, коли
Цитировать
сделал тестовое приложение (без своих классов), так там работает...
, то проблема где-то у тебя.
Смотри в отладчике window. Оно должно уже быть создано.


Название: Re: X11 window fullscreen
Отправлено: alexlogvinenkoit от Март 21, 2012, 14:02
WM?


Название: Re: X11 window fullscreen
Отправлено: GreatSnake от Март 21, 2012, 14:06
WM?
Window Manager


Название: Re: X11 window fullscreen
Отправлено: GreatSnake от Март 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();
}
 
Всё работает...


Название: Re: X11 window fullscreen
Отправлено: alexlogvinenkoit от Март 21, 2012, 14:13
Я, наверное, понял в чем причина: у меня X11 окно - это Child другого X11 окна... В винде тоже такая проблема была, там решил функцией SetParent(HWND, HWND)... Здесь, наверное, так же сделаю...

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

Спасибо! Очень помог!


Название: Re: X11 window fullscreen
Отправлено: GreatSnake от Март 21, 2012, 14:18
у меня X11 окно - это Child другого X11 окна...
Ну дык, конечно, WM работает только с окнами созданными на root-window.

Цитировать
Можно как-то без удаления окна обойтись?
см. XReparentWindow()


Название: Re: X11 window fullscreen
Отправлено: alexlogvinenkoit от Март 21, 2012, 14:48
Заработало!

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

Спасибо огромное!


Название: Re: X11 window fullscreen
Отправлено: alexlogvinenkoit от Март 27, 2012, 11:05
Еще раз здрасьте!

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

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

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

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

Спасибо!


Название: Re: X11 window fullscreen
Отправлено: GreatSnake от Март 27, 2012, 11:14
Не уверен, но может поможет XSelectInput().
Давно уже на чистом XLib-e не писал.


Название: Re: X11 window fullscreen
Отправлено: alexlogvinenkoit от Март 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-и)...


Название: Re: X11 window fullscreen
Отправлено: alexlogvinenkoit от Март 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... Насчет первого - я практически уверен, что не заработает... Насчет второго - пока что не знаю, попробую, отпишу)


Название: Re: X11 window fullscreen
Отправлено: alexlogvinenkoit от Апрель 05, 2012, 18:40
Да, без mail-лупа не обойтись никак... Пока что настроил поток, и мьютексами лочу, делаю что мне надо, а потом разлачиваю... Т.е. лок - получить событие - анлок - если событие = кнопка отпущена - лок - в полноэкранный/оконный режим - анлок... Геморно, но работает... Единственное но - это то, что 1 раз отрабатывает, на 2-й уже долго тупит и отрабатывает...
В Windows эта же процедура занимает очень мало времени, хотя и там и тут идет ReparentWindow (без пересоздавания окна).

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

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

Спасибо!