@@ -151,7 +151,6 @@ bool CWinSystemX11::DestroyWindow()
151151 CWinEventsX11Imp::Quit ();
152152
153153 XUnmapWindow (m_dpy, m_mainWindow);
154- XSync (m_dpy,TRUE );
155154 XDestroyWindow (m_dpy, m_glWindow);
156155 XDestroyWindow (m_dpy, m_mainWindow);
157156 m_glWindow = 0 ;
@@ -208,7 +207,6 @@ bool CWinSystemX11::ResizeWindow(int newWidth, int newHeight, int newLeft, int n
208207
209208bool CWinSystemX11::SetFullScreen (bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
210209{
211-
212210#if defined(HAS_XRANDR)
213211 XOutput out;
214212 XMode mode;
@@ -248,6 +246,28 @@ bool CWinSystemX11::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl
248246 currmode.hz != mode.hz || currmode.id != mode.id )
249247 {
250248 CLog::Log (LOGNOTICE, " CWinSystemX11::SetFullScreen - calling xrandr" );
249+
250+ // remember last position of mouse
251+ Window root_return, child_return;
252+ int root_x_return, root_y_return;
253+ int win_x_return, win_y_return;
254+ unsigned int mask_return;
255+ bool isInWin = XQueryPointer (m_dpy, m_mainWindow, &root_return, &child_return,
256+ &root_x_return, &root_y_return,
257+ &win_x_return, &win_y_return,
258+ &mask_return);
259+
260+ if (isInWin)
261+ {
262+ m_MouseX = win_x_return;
263+ m_MouseY = win_y_return;
264+ }
265+ else
266+ {
267+ m_MouseX = -1 ;
268+ m_MouseY = -1 ;
269+ }
270+
251271 OnLostDevice ();
252272 m_bIsInternalXrr = true ;
253273 g_xrandr.SetMode (out, mode);
@@ -659,13 +679,13 @@ bool CWinSystemX11::Restore()
659679bool CWinSystemX11::Hide ()
660680{
661681 XUnmapWindow (m_dpy, m_mainWindow);
662- XSync (m_dpy, False );
682+ XFlush (m_dpy);
663683 return true ;
664684}
665685bool CWinSystemX11::Show (bool raise)
666686{
667687 XMapWindow (m_dpy, m_mainWindow);
668- XSync (m_dpy, False );
688+ XFlush (m_dpy);
669689 m_minimized = false ;
670690 return true ;
671691}
@@ -688,7 +708,6 @@ void CWinSystemX11::NotifyXRREvent()
688708 {
689709 UpdateResolutions ();
690710 }
691- m_bIsInternalXrr = false ;
692711
693712 XOutput *out = g_xrandr.GetOutput (m_userOutput);
694713 XMode mode = g_xrandr.GetCurrentMode (m_userOutput);
@@ -773,16 +792,24 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std:
773792{
774793 bool changeWindow = false ;
775794 bool changeSize = false ;
776- bool mouseActive = false ;
777- float mouseX = 0 ;
778- float mouseY = 0 ;
779- int x0 = 0 ;
780- int y0 = 0 ;
795+ float mouseX = 0.5 ;
796+ float mouseY = 0.5 ;
797+
798+ if (!m_mainWindow)
799+ {
800+ g_Mouse.SetActive (false );
801+ }
781802
782803 if (m_mainWindow && ((m_bFullScreen != fullscreen) || m_currentOutput.compare (output) != 0 || m_windowDirty))
783804 {
784- mouseActive = g_Mouse.IsActive ();
785- if (mouseActive)
805+ // set mouse to last known position
806+ // we can't trust values after an xrr event
807+ if (m_bIsInternalXrr && m_MouseX >= 0 && m_MouseY >= 0 )
808+ {
809+ mouseX = (float )m_MouseX/m_nWidth;
810+ mouseY = (float )m_MouseY/m_nHeight;
811+ }
812+ else if (!m_windowDirty)
786813 {
787814 Window root_return, child_return;
788815 int root_x_return, root_y_return;
@@ -792,15 +819,15 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std:
792819 &root_x_return, &root_y_return,
793820 &win_x_return, &win_y_return,
794821 &mask_return);
822+
795823 if (isInWin)
796824 {
797825 mouseX = (float )win_x_return/m_nWidth;
798826 mouseY = (float )win_y_return/m_nHeight;
799- g_Mouse.SetActive (false );
800827 }
801- else
802- mouseActive = false ;
803828 }
829+
830+ g_Mouse.SetActive (false );
804831 OnLostDevice ();
805832 DestroyWindow ();
806833 m_windowDirty = true ;
@@ -825,6 +852,8 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std:
825852 Colormap cmap;
826853 XSetWindowAttributes swa;
827854 XVisualInfo *vi;
855+ int x0 = 0 ;
856+ int y0 = 0 ;
828857
829858 XOutput *out = g_xrandr.GetOutput (output);
830859 if (!out)
@@ -931,7 +960,6 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std:
931960 class_hints->res_class = (char *)classString.c_str ();
932961 class_hints->res_name = (char *)classString.c_str ();
933962
934- XSync (m_dpy,False);
935963 XSetWMProperties (m_dpy, m_mainWindow, &windowName, &iconName,
936964 NULL , 0 , NULL , wm_hints,
937965 class_hints);
@@ -942,18 +970,15 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std:
942970 Atom wmDeleteMessage = XInternAtom (m_dpy, " WM_DELETE_WINDOW" , False);
943971 XSetWMProtocols (m_dpy, m_mainWindow, &wmDeleteMessage, 1 );
944972 }
945- XMapRaised (m_dpy, m_glWindow);
946- XMapRaised (m_dpy, m_mainWindow);
947973
948- if (fullscreen)
949- XMoveWindow (m_dpy, m_mainWindow, x0, y0 );
974+ // placement of window may follow mouse
975+ XWarpPointer (m_dpy, None, m_mainWindow, 0 , 0 , 0 , 0 , mouseX*width, mouseY*height );
950976
951- XSync (m_dpy,TRUE );
977+ XMapRaised (m_dpy, m_glWindow);
978+ XMapRaised (m_dpy, m_mainWindow);
952979
953- if (changeWindow && mouseActive)
954- {
955- XWarpPointer (m_dpy, None, m_mainWindow, 0 , 0 , 0 , 0 , mouseX*width, mouseY*height);
956- }
980+ // discard events generated by creating the window, i.e. xrr events
981+ XSync (m_dpy, TRUE );
957982
958983 CDirtyRegionList dr;
959984 RefreshGlxContext (m_currentOutput.compare (output) != 0 );
@@ -962,6 +987,7 @@ bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std:
962987 g_graphicsContext.Flip (dr);
963988 g_Windowing.ResetVSync ();
964989 m_windowDirty = false ;
990+ m_bIsInternalXrr = false ;
965991
966992 CSingleLock lock (m_resourceSection);
967993 // tell any shared resources
0 commit comments