--- src/kernel/qapplication_x11.cpp.sav 2003-08-06 18:41:22.000000000 +0200 +++ src/kernel/qapplication_x11.cpp 2003-08-06 18:42:22.000000000 +0200 @@ -254,6 +254,7 @@ Atom qt_net_wm_state = 0; Atom qt_net_wm_state_modal = 0; Atom qt_net_wm_state_max_v = 0; Atom qt_net_wm_state_max_h = 0; +Atom qt_net_wm_state_fullscreen = 0; Atom qt_net_wm_window_type = 0; Atom qt_net_wm_window_type_normal = 0; Atom qt_net_wm_window_type_dialog = 0; @@ -1420,6 +1421,62 @@ void qt_get_net_virtual_roots() } } +void qt_net_change_state(const QWidget* w, Atom state, bool set) +{ + if( w->isShown()) { // managed by WM + XEvent ev; + ev.xclient.type = ClientMessage; + ev.xclient.message_type = qt_net_wm_state; + ev.xclient.display = w->x11Display(); + ev.xclient.window = w->winId(); + ev.xclient.format = 32; + ev.xclient.data.l[ 0 ] = set ? 1 : 0; + ev.xclient.data.l[ 1 ] = state; + ev.xclient.data.l[ 2 ] = 0; + ev.xclient.data.l[ 3 ] = 0; + ev.xclient.data.l[ 4 ] = 0; + XSendEvent( w->x11Display(), RootWindow(w->x11Display(), w->x11Screen() ), False, + SubstructureRedirectMask|SubstructureNotifyMask, &ev ); + } else { + Atom ret; + int format, e; + unsigned char *data = 0; + unsigned long nitems, after; + e = XGetWindowProperty( w->x11Display(), w->winId(), + qt_net_wm_state, 0, 1024, False, + XA_ATOM, &ret, &format, &nitems, + &after, &data); + if (e == Success && ret == XA_ATOM && format == 32 && + nitems > 0) { + Atom *states = (Atom *) data; + Atom *new_states = new Atom[ nitems + 1 ]; + unsigned long i; + unsigned long new_count = 0; + for (i = 0; i < nitems; i++) { + if (states[i] == state) { + if(set) { + delete[] new_states; + return; // already set, no need to change anything + } + // else don't copy + } else + new_states[ new_count++ ] = states[ i ]; + } + if( set ) + new_states[ new_count++ ] = state; + XChangeProperty( w->x11Display(), w->winId(), qt_net_wm_state, XA_ATOM, 32, PropModeReplace, + (unsigned char *) new_states, new_count ); + delete[] new_states; + } else { + Atom states[ 1 ] = { state }; + XChangeProperty( w->x11Display(), w->winId(), qt_net_wm_state, XA_ATOM, 32, PropModeReplace, + (unsigned char *) states, set ? 1 : 0 ); + } + if (data) + XFree(data); + } +} + void qt_x11_create_wm_client_leader() { if ( qt_x11_wm_client_leader ) return; @@ -1912,6 +1965,7 @@ void qt_init_internal( int *argcptr, cha qt_x11_intern_atom( "_NET_WM_STATE_MODAL", &qt_net_wm_state_modal ); qt_x11_intern_atom( "_NET_WM_STATE_MAXIMIZED_VERT", &qt_net_wm_state_max_v ); qt_x11_intern_atom( "_NET_WM_STATE_MAXIMIZED_HORZ", &qt_net_wm_state_max_h ); + qt_x11_intern_atom( "_NET_WM_STATE_FULLSCREEN", &qt_net_wm_state_fullscreen ); qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE", &qt_net_wm_window_type ); qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_NORMAL", &qt_net_wm_window_type_normal ); @@ -3357,6 +3411,7 @@ int QApplication::x11ProcessEvent( XEven &after, &data); bool isMaximized = FALSE; + bool isFullScreen = FALSE; if (e == Success && ret == XA_ATOM && format == 32 && nitems > 0) { Atom *states = (Atom *) data; @@ -3366,8 +3421,9 @@ int QApplication::x11ProcessEvent( XEven if (states[i] == qt_net_wm_state_max_v || states[i] == qt_net_wm_state_max_h) { isMaximized = TRUE; - break; - } + } else if (states[i] == qt_net_wm_state_fullscreen) { + isFullScreen = TRUE; + } } } @@ -3375,6 +3431,21 @@ int QApplication::x11ProcessEvent( XEven widget->setWState(WState_Maximized); else widget->clearWState(WState_Maximized); + + if( qt_net_supports(qt_net_wm_state_fullscreen)) { + if( !isFullScreen && widget->isFullScreen()) { + // if there was QWidget::showFullScreen( bool ), that + // wouldn't mess with maximize state etc., this could be just + // widget->showFullScreen( false ) + widget->topData()->fullscreen = 0; + QEvent e( QEvent::ShowNormal ); + QApplication::sendSpontaneousEvent( widget, &e ); + } else if( isFullScreen && !widget->isFullScreen()) { + widget->topData()->fullscreen = 1; + QEvent e( QEvent::ShowFullScreen ); + QApplication::sendSpontaneousEvent( widget, &e ); + } + } if (data) XFree(data); --- src/kernel/qwidget.cpp.sav 2003-08-06 18:41:22.000000000 +0200 +++ src/kernel/qwidget.cpp 2003-08-06 18:42:18.000000000 +0200 @@ -5716,11 +5716,19 @@ void QWidget::reparent( QWidget *parent strange effects on desktop changes or when the user raises other windows. - Future X11 window managers that follow modern post-ICCCM - specifications may support full-screen mode properly. + X11 window managers that follow modern post-ICCCM + specifications support full-screen mode properly. \sa showNormal(), showMaximized(), show(), hide(), isVisible() */ + +#if defined(Q_WS_X11) +#include +extern Atom qt_net_wm_state_fullscreen; +extern bool qt_net_supports(Atom); +extern void qt_net_change_state(const QWidget*,Atom,bool); +#endif + #if (QT_VERSION-0 >= 0x040000) #error "QWidget::showFullScreen() should be virtual (see change #16156)" #endif @@ -5728,6 +5736,20 @@ void QWidget::showFullScreen() { if ( !isTopLevel() ) return; +#if defined(Q_WS_X11) + if( qt_net_supports(qt_net_wm_state_fullscreen)) { + if( topData()->fullscreen ) { + show(); + return; + } + qt_net_change_state(this,qt_net_wm_state_fullscreen,true); + topData()->fullscreen = 1; + show(); + QEvent e( QEvent::ShowFullScreen ); + QApplication::sendEvent( this, &e ); + return; + } +#endif if ( topData()->fullscreen ) { show(); raise(); --- src/kernel/qwidget_x11.cpp.sav 2003-08-06 18:41:22.000000000 +0200 +++ src/kernel/qwidget_x11.cpp 2003-08-06 18:42:18.000000000 +0200 @@ -111,6 +111,7 @@ extern Atom qt_net_wm_state; extern Atom qt_net_wm_state_modal; extern Atom qt_net_wm_state_max_v; extern Atom qt_net_wm_state_max_h; +extern Atom qt_net_wm_state_fullscreen; extern Atom qt_net_wm_state_stays_on_top; extern Atom qt_net_wm_window_type; extern Atom qt_net_wm_window_type_normal; @@ -126,6 +127,7 @@ extern bool qt_broken_wm; // defined in qapplication_x11.cpp extern bool qt_net_supports(Atom); +extern void qt_net_change_state(const QWidget*,Atom,bool); extern unsigned long *qt_net_virtual_root_list; #if defined (QT_TABLET_SUPPORT) @@ -1733,9 +1735,13 @@ void QWidget::showNormal() { if ( isTopLevel() ) { if ( topData()->fullscreen ) { - // when reparenting, preserve some widget flags - reparent( 0, topData()->savedFlags, QPoint(0,0) ); - topData()->fullscreen = 0; + if( qt_net_supports(qt_net_wm_state_fullscreen)) { + qt_net_change_state(this,qt_net_wm_state_fullscreen,false); + } else { + // when reparenting, preserve some widget flags + reparent( 0, topData()->savedFlags, QPoint(0,0) ); + topData()->fullscreen = 0; + } } QRect r = topData()->normalGeometry; if ( r.width() >= 0 ) { @@ -1749,7 +1755,7 @@ void QWidget::showNormal() extra->topextra->fullscreen = 0; if ( !isVisible() ) { show(); - } else { + } else if( testWState( WState_Minimized )) { showWindow(); } QEvent e( QEvent::ShowNormal );