[Spice-devel,8/8] fix failure to start in fullscreen mode

Submitted by Christophe Fergeau on Aug. 17, 2011, 6:25 p.m.

Details

Message ID 1313580353-3086-9-git-send-email-cfergeau@redhat.com
State New, archived
Headers show

Not browsing as part of any series.

Commit Message

Christophe Fergeau Aug. 17, 2011, 6:25 p.m.
From: Yonit Halperin <yhalperi@redhat.com>

Commit 419222f0f3
client: fix endless recursion in rearrange_monitors, RHBZ #692976
introduced a regression: after a resolution change in the guest, it's
no longer possible to start spicec in full screen.

when resizing the screen, the monitors mode (resolution) should be set
according to the size of the screen (which is the dimension of the
corresponding surface). This is what rearrange_monitors does, and it does it
for all monitor-screen pairs. So rearrange_monitors should be called, but
according to what Christophe found, it should be called before the actual
resize takes place. However, since it is not longer called from the Screen
class (for avoiding the #692976), and should be called before Screen::resize it
should be able to receive sizes as parameter and not only use the Screen::size.
Attached a patch. Still need to test it thoroughly

Fixes rhbz #728252
---
 client/application.cpp |   45 ++++++++++++++++++++++++++++++++++-----------
 client/application.h   |    5 +++--
 2 files changed, 37 insertions(+), 13 deletions(-)

Patch hide | download patch | download mbox

diff --git a/client/application.cpp b/client/application.cpp
index b43cf1d..c89f039 100644
--- a/client/application.cpp
+++ b/client/application.cpp
@@ -1368,7 +1368,8 @@  void Application::on_screen_unlocked(RedScreen& screen)
 
 void Application::rearrange_monitors(bool force_capture,
                                      bool enter_full_screen,
-                                     RedScreen* screen)
+                                     RedScreen* screen,
+                                     std::vector<SpicePoint> *sizes)
 {
     bool capture;
     bool toggle_full_screen;
@@ -1386,7 +1387,7 @@  void Application::rearrange_monitors(bool force_capture,
         hide();
     }
 #endif
-    prepare_monitors();
+    prepare_monitors(sizes);
     position_screens();
     if (enter_full_screen) {
         // toggling to full screen
@@ -1445,16 +1446,20 @@  void Application::assign_monitors()
     }
 }
 
-void Application::prepare_monitors()
+void Application::prepare_monitors(std::vector<SpicePoint> *sizes)
 {
     //todo: test match of monitors size/position against real world size/position
     for (int i = 0; i < (int)_screens.size(); i++) {
         Monitor* mon;
         if (_screens[i] && (mon = _screens[i]->get_monitor())) {
-
             if (_screens[i]->is_size_locked()) {
-                SpicePoint size = _screens[i]->get_size();
-                mon->set_mode(size.x, size.y);
+                if (sizes) {
+                    mon->set_mode((*sizes)[i].x, (*sizes)[i].y);
+                    LOG_INFO("SET");
+                } else {
+                    SpicePoint size = _screens[i]->get_size();
+                    mon->set_mode(size.x, size.y);
+                }
             } else {
                 SpicePoint size = mon->get_size();
                 _screens[i]->resize(size.x, size.y);
@@ -1590,14 +1595,32 @@  bool Application::toggle_full_screen()
 
 void Application::resize_screen(RedScreen *screen, int width, int height)
 {
-    Monitor* mon;
+    std::vector<SpicePoint> sizes;
+    std::vector<SpicePoint> *p_sizes = NULL;
+    bool capture = false;
+
     if (_full_screen) {
-        if ((mon = screen->get_monitor())) {
-            mon->set_mode(width, height);
-        }
+        capture = (_main_screen == screen) && _active_screen &&
+                                              _active_screen->is_mouse_captured();
+        sizes.resize(_screens.size());
+        for (int i = 0; i < (int)_screens.size(); i++) {
+            if (_screens[i]) {
+                if (_screens[i] == screen) {
+                    sizes[i].x = width;
+                    sizes[i].y = height;
+                    LOG_INFO("SET");
+                } else {
+                    sizes[i] = _screens[i]->get_size();
+                }
+            }
+         }
+        p_sizes = &sizes;
     }
+    rearrange_monitors(false, false, NULL, p_sizes);
     screen->resize(width, height);
-    rearrange_monitors(false, false);
+    if (capture) {
+        screen->capture_mouse();
+    }
     if (screen->is_out_of_sync()) {
         _out_of_sync = true;
         /* If the client monitor cannot handle the guest resolution
diff --git a/client/application.h b/client/application.h
index 8079753..c70c7fa 100644
--- a/client/application.h
+++ b/client/application.h
@@ -306,10 +306,11 @@  private:
     void destroy_monitors();
     void assign_monitors();
     void restore_monitors();
-    void prepare_monitors();
+    void prepare_monitors(std::vector<SpicePoint> *sizes);
     void rearrange_monitors(bool force_capture,
                             bool enter_full_screen,
-                            RedScreen* screen = NULL);
+                            RedScreen* screen = NULL,
+                            std::vector<SpicePoint> *sizes = NULL);
     void position_screens();
     void show_full_screen();
     void send_key_down(RedKey key);