summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYonit Halperin <yhalperi@redhat.com>2011-07-21 10:07:57 +0300
committerAlon Levy <alevy@redhat.com>2011-07-21 15:09:30 +0300
commit858596bb483c495998d738f394d39104e14931be (patch)
tree68f83102d9458adb818c1930303fc0ae4615d36b
parent3bc4fd4621798674b2a6d9537180d91ccde8ee0d (diff)
downloadspice-858596bb483c495998d738f394d39104e14931be.tar.gz
spice-858596bb483c495998d738f394d39104e14931be.tar.xz
spice-858596bb483c495998d738f394d39104e14931be.zip
client: fix endless recursion in rearrange_monitors, RHBZ #692976
I changed RedScreen::resize not to call rearrange_monitors. Instead, the monitor should be configured correctly from Application, before calling resize. In addition, I made some cleanups to allow reusing rearrange_monitors code.
-rw-r--r--client/application.cpp94
-rw-r--r--client/application.h4
-rw-r--r--client/screen.cpp4
-rw-r--r--client/screen.h2
4 files changed, 54 insertions, 50 deletions
diff --git a/client/application.cpp b/client/application.cpp
index 810a6dd1..b43cf1d2 100644
--- a/client/application.cpp
+++ b/client/application.cpp
@@ -665,25 +665,9 @@ RedScreen* Application::get_screen(int id)
if (id != 0) {
if (_full_screen) {
- bool capture;
-
mon = get_monitor(id);
- capture = release_capture();
screen->set_monitor(mon);
- prepare_monitors();
- position_screens();
- screen->show_full_screen();
- if (screen->is_out_of_sync()) {
- _out_of_sync = true;
- /* If the client monitor cannot handle the guest resolution
- drop back to windowed mode */
- exit_full_screen();
- }
-
- if (capture) {
- _main_screen->activate();
- _main_screen->capture_mouse();
- }
+ rearrange_monitors(false, true, screen);
} else {
screen->show(false, _main_screen);
}
@@ -771,13 +755,7 @@ void Application::on_screen_destroyed(int id, bool was_captured)
}
_screens[id] = NULL;
if (reposition) {
- bool capture = was_captured || release_capture();
- prepare_monitors();
- position_screens();
- if (capture) {
- _main_screen->activate();
- _main_screen->capture_mouse();
- }
+ rearrange_monitors(was_captured, false);
}
}
@@ -1388,20 +1366,51 @@ void Application::on_screen_unlocked(RedScreen& screen)
screen.resize(SCREEN_INIT_WIDTH, SCREEN_INIT_HEIGHT);
}
-bool Application::rearrange_monitors(RedScreen& screen)
+void Application::rearrange_monitors(bool force_capture,
+ bool enter_full_screen,
+ RedScreen* screen)
{
- if (!_full_screen) {
- return false;
+ bool capture;
+ bool toggle_full_screen;
+
+ if (!_full_screen && !enter_full_screen) {
+ return;
+ }
+
+ toggle_full_screen = enter_full_screen && !screen;
+ capture = release_capture();
+#ifndef WIN32
+ if (toggle_full_screen) {
+ /* performing hide during resolution changes resulted in
+ missing WM_KEYUP events */
+ hide();
}
- bool capture = release_capture();
+#endif
prepare_monitors();
position_screens();
- if (capture && _main_screen != &screen) {
- capture = false;
- _main_screen->activate();
+ if (enter_full_screen) {
+ // toggling to full screen
+ if (toggle_full_screen) {
+ show_full_screen();
+ _main_screen->activate();
+
+ } else { // already in full screen mode and a new screen is displayed
+ screen->show_full_screen();
+ if (screen->is_out_of_sync()) {
+ _out_of_sync = true;
+ /* If the client monitor cannot handle the guest resolution
+ drop back to windowed mode */
+ exit_full_screen();
+ }
+ }
+ }
+
+ if (force_capture || capture) {
+ if (!toggle_full_screen) {
+ _main_screen->activate();
+ }
_main_screen->capture_mouse();
}
- return capture;
}
Monitor* Application::find_monitor(int id)
@@ -1518,20 +1527,8 @@ void Application::enter_full_screen()
{
LOG_INFO("");
_changing_screens = true;
- bool capture = release_capture();
assign_monitors();
-#ifndef WIN32
- /* performing hide during resolution changes resulted in
- missing WM_KEYUP events */
- hide();
-#endif
- prepare_monitors();
- position_screens();
- show_full_screen();
- _main_screen->activate();
- if (capture) {
- _main_screen->capture_mouse();
- }
+ rearrange_monitors(false, true);
_changing_screens = false;
_full_screen = true;
/* If the client monitor cannot handle the guest resolution drop back
@@ -1593,7 +1590,14 @@ bool Application::toggle_full_screen()
void Application::resize_screen(RedScreen *screen, int width, int height)
{
+ Monitor* mon;
+ if (_full_screen) {
+ if ((mon = screen->get_monitor())) {
+ mon->set_mode(width, height);
+ }
+ }
screen->resize(width, height);
+ rearrange_monitors(false, false);
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 4133dfe6..80797531 100644
--- a/client/application.h
+++ b/client/application.h
@@ -216,7 +216,6 @@ public:
void on_disconnecting();
void on_visibility_start(int screen_id);
- bool rearrange_monitors(RedScreen& screen);
void enter_full_screen();
void exit_full_screen();
bool toggle_full_screen();
@@ -308,6 +307,9 @@ private:
void assign_monitors();
void restore_monitors();
void prepare_monitors();
+ void rearrange_monitors(bool force_capture,
+ bool enter_full_screen,
+ RedScreen* screen = NULL);
void position_screens();
void show_full_screen();
void send_key_down(RedKey key);
diff --git a/client/screen.cpp b/client/screen.cpp
index caa5d4f7..e0857814 100644
--- a/client/screen.cpp
+++ b/client/screen.cpp
@@ -186,11 +186,7 @@ void RedScreen::resize(int width, int height)
_size.y = height;
create_composit_area();
if (_full_screen) {
- bool cuptur = _owner.rearrange_monitors(*this);
__show_full_screen();
- if (cuptur) {
- capture_mouse();
- }
} else {
bool cuptur = is_mouse_captured();
if (cuptur) {
diff --git a/client/screen.h b/client/screen.h
index 2b40d774..e7db4ef9 100644
--- a/client/screen.h
+++ b/client/screen.h
@@ -62,6 +62,8 @@ public:
void attach_layer(ScreenLayer& layer);
void detach_layer(ScreenLayer& layer);
void on_layer_changed(ScreenLayer& layer);
+ /* When resizing on full screen mode, the monitor must be configured
+ * correctly before calling resize*/
void resize(int width, int height);
void set_name(const std::string& name);
uint64_t invalidate(const SpiceRect& rect, bool urgent);