summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorYaniv Kamay <ykamay@redhat.com>2009-12-28 00:17:42 +0200
committerYaniv Kamay <ykamay@redhat.com>2009-12-28 12:35:32 +0200
commitcced1b1cff4002e2402936ff033ce985668e59e5 (patch)
tree002c66212e423c5536080e5dd6f6d046501919df /client
parent941ba9bf5ca9a8812e7893848943c2cec6a5e6a6 (diff)
downloadspice-cced1b1cff4002e2402936ff033ce985668e59e5.tar.gz
spice-cced1b1cff4002e2402936ff033ce985668e59e5.tar.xz
spice-cced1b1cff4002e2402936ff033ce985668e59e5.zip
client: improve screen resizing
Screen now have to modes locked and unlocked. In unlocked mode, the application can change screen size and so reduce resolution changing. The application can also choose to change window size while not in full screen mode. In locked mode the application must ewtain locker screen size setting.
Diffstat (limited to 'client')
-rw-r--r--client/application.cpp88
-rw-r--r--client/application.h2
-rw-r--r--client/display_channel.cpp31
-rw-r--r--client/screen.cpp17
-rw-r--r--client/screen.h8
5 files changed, 110 insertions, 36 deletions
diff --git a/client/application.cpp b/client/application.cpp
index 8345f390..724eb338 100644
--- a/client/application.cpp
+++ b/client/application.cpp
@@ -226,7 +226,11 @@ void GUILayer::set_sticky(bool is_on)
void GUILayer::on_size_changed()
{
- set_info_mode();
+ if (_splash_mode) {
+ set_splash_mode();
+ } else {
+ set_info_mode();
+ }
}
void StickyKeyTimer::response(AbstractProcessLoop& events_loop)
@@ -499,31 +503,35 @@ RedScreen* Application::get_screen(int id)
}
if (!(screen = _screens[id])) {
- Monitor* mon;
+ Monitor* mon = find_monitor(id);
+ Point size;
- if (_client.is_auto_display_res() && (mon = find_monitor(id))) {
+ if (_full_screen && mon) {
Point size = mon->get_size();
- screen = _screens[id] = new RedScreen(*this, id, _title, size.x, size.y);
} else {
- screen = _screens[id] = new RedScreen(*this, id, _title, SCREEN_INIT_WIDTH,
- SCREEN_INIT_HEIGHT);
+ size.x = SCREEN_INIT_WIDTH;
+ size.y = SCREEN_INIT_HEIGHT;
}
- if (_full_screen) {
- bool capture;
-
- mon = get_monitor(id);
- capture = release_capture();
- screen->set_monitor(mon);
- position_screens();
- screen->show_full_screen();
- prepare_monitors();
-
- if (capture) {
- _main_screen->activate();
- _main_screen->capture_mouse();
+ screen = _screens[id] = new RedScreen(*this, id, _title, size.x, size.y);
+
+ if (id != 0) {
+ if (_full_screen) {
+ bool capture;
+
+ mon = get_monitor(id);
+ capture = release_capture();
+ screen->set_monitor(mon);
+ position_screens();
+ screen->show_full_screen();
+ prepare_monitors();
+
+ if (capture) {
+ _main_screen->activate();
+ _main_screen->capture_mouse();
+ }
+ } else {
+ screen->show(false, _main_screen);
}
- } else if (id != 0) {
- screen->show(false, _main_screen);
}
} else {
screen = screen->ref();
@@ -962,6 +970,15 @@ void Application::on_app_deactivated()
#endif
}
+void Application::on_screen_unlocked(RedScreen& screen)
+{
+ if (_full_screen) {
+ return;
+ }
+
+ screen.resize(SCREEN_INIT_WIDTH, SCREEN_INIT_HEIGHT);
+}
+
bool Application::rearrange_monitors(RedScreen& screen)
{
if (!_full_screen) {
@@ -1012,14 +1029,20 @@ void Application::assign_monitors()
void Application::prepare_monitors()
{
+ //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())) {
- Point size = _screens[i]->get_size();
- mon->set_mode(size.x, size.y);
+
+ if (_screens[i]->is_size_locked()) {
+ Point size = _screens[i]->get_size();
+ mon->set_mode(size.x, size.y);
+ } else {
+ Point size = mon->get_size();
+ _screens[i]->resize(size.x, size.y);
+ }
}
}
- //todo: test match of monitors size/position against real world size/position
}
void Application::restore_monitors()
@@ -1097,6 +1120,16 @@ void Application::enter_full_screen()
_full_screen = true;
}
+void Application::restore_screens_size()
+{
+ for (int i = 0; i < (int)_screens.size(); i++) {
+ if (_screens[i]->is_size_locked()) {
+ continue;
+ }
+ _screens[i]->resize(SCREEN_INIT_WIDTH, SCREEN_INIT_HEIGHT);
+ }
+}
+
void Application::exit_full_screen()
{
if (!_full_screen) {
@@ -1116,6 +1149,7 @@ void Application::exit_full_screen()
}
restore_monitors();
_full_screen = false;
+ restore_screens_size();
show();
_main_screen->activate();
}
@@ -1606,12 +1640,6 @@ bool Application::process_cmd_line(int argc, char** argv)
}
_client.init(host.c_str(), port, sport, password.c_str(), auto_display_res);
- if (auto_display_res) {
- Monitor* mon = find_monitor(0);
- ASSERT(mon);
- Point size = mon->get_size();
- _main_screen->set_mode(size.x, size.y, 32);
- }
if (full_screen) {
enter_full_screen();
diff --git a/client/application.h b/client/application.h
index da2d4218..c5e0e141 100644
--- a/client/application.h
+++ b/client/application.h
@@ -125,6 +125,7 @@ public:
RedScreen* find_screen(int id);
RedScreen* get_screen(int id);
+ void on_screen_unlocked(RedScreen& screen);
void on_screen_destroyed(int id, bool was_captured);
void on_mouse_motion(int dx, int dy, int buttons_state);
void on_mouse_down(int button, int buttons_state);
@@ -176,6 +177,7 @@ private:
bool do_connect();
bool do_disconnect();
+ void restore_screens_size();
Monitor* find_monitor(int id);
Monitor* get_monitor(int id);
void init_monitors();
diff --git a/client/display_channel.cpp b/client/display_channel.cpp
index 9f8fba80..0050a21c 100644
--- a/client/display_channel.cpp
+++ b/client/display_channel.cpp
@@ -60,7 +60,8 @@ public:
{
Application* app = (Application*)events_loop.get_owner();
_channel.destroy_canvas();
- _channel.screen()->set_mode(_width, _height, _depth);
+ _channel.screen()->lock_size();
+ _channel.screen()->resize(_width, _height);
_channel.create_canvas(app->get_canvas_types(), _width, _height, _depth);
}
@@ -71,6 +72,22 @@ private:
int _depth;
};
+class UnlockScreenEvent: public Event {
+public:
+ UnlockScreenEvent(RedScreen* screen)
+ : _screen (screen->ref())
+ {
+ }
+
+ virtual void response(AbstractProcessLoop& events_loop)
+ {
+ (*_screen)->unlock_size();
+ }
+
+private:
+ AutoRef<RedScreen> _screen;
+};
+
class DisplayMarkEvent: public Event {
public:
DisplayMarkEvent(int screen_id)
@@ -1088,9 +1105,14 @@ void DisplayChannel::on_disconnect()
if (screen()) {
screen()->set_update_interrupt_trigger(NULL);
}
+
AutoRef<DetachChannelsEvent> detach_channels(new DetachChannelsEvent(*this));
get_client().push_event(*detach_channels);
- detach_from_screen(get_client().get_application());
+ if (screen()) {
+ AutoRef<UnlockScreenEvent> unlock_event(new UnlockScreenEvent(screen()));
+ get_client().push_event(*unlock_event);
+ detach_from_screen(get_client().get_application());
+ }
get_client().deactivate_interval_timer(*_streams_timer);
AutoRef<SyncEvent> sync_event(new SyncEvent());
get_client().push_event(*sync_event);
@@ -1280,7 +1302,12 @@ void DisplayChannel::handle_reset(RedPeer::InMessage *message)
if (_canvas.get()) {
_canvas->clear();
}
+
AutoRef<ResetTimer> reset_timer(new ResetTimer(screen()->ref(), get_client()));
+
+ AutoRef<UnlockScreenEvent> unlock_event(new UnlockScreenEvent(screen()));
+ get_client().push_event(*unlock_event);
+
detach_from_screen(get_client().get_application());
_palette_cache.clear();
diff --git a/client/screen.cpp b/client/screen.cpp
index e9bae8b2..29b40bf6 100644
--- a/client/screen.cpp
+++ b/client/screen.cpp
@@ -83,6 +83,7 @@ RedScreen::RedScreen(Application& owner, int id, const std::wstring& name, int w
, _periodic_update (false)
, _key_interception (false)
, _update_by_timer (true)
+ , _size_locked (false)
, _forec_update_timer (0)
, _update_timer (new UpdateTimer(this))
, _composit_area (NULL)
@@ -148,7 +149,7 @@ void RedScreen::show(bool activate, RedScreen* pos)
RedScreen* RedScreen::ref()
{
- _refs++;
+ ++_refs;
return this;
}
@@ -179,7 +180,7 @@ void RedScreen::adjust_window_rect(int x, int y)
_window.move_and_resize(x, y, _size.x, _size.y);
}
-void RedScreen::set_mode(int width, int height, int depth)
+void RedScreen::resize(int width, int height)
{
RecurciveLock lock(_update_lock);
_size.x = width;
@@ -204,6 +205,18 @@ void RedScreen::set_mode(int width, int height, int depth)
notify_new_size();
}
+void RedScreen::lock_size()
+{
+ ASSERT(!_size_locked);
+ _size_locked = true;
+}
+
+void RedScreen::unlock_size()
+{
+ _size_locked = false;
+ _owner.on_screen_unlocked(*this);
+}
+
void RedScreen::set_name(const std::wstring& name)
{
if (!name.empty()) {
diff --git a/client/screen.h b/client/screen.h
index 3321c2ff..5952fe81 100644
--- a/client/screen.h
+++ b/client/screen.h
@@ -58,7 +58,7 @@ public:
void attach_layer(ScreenLayer& layer);
void detach_layer(ScreenLayer& layer);
void on_layer_changed(ScreenLayer& layer);
- void set_mode(int width, int height, int depth);
+ void resize(int width, int height);
void set_name(const std::wstring& name);
uint64_t invalidate(const Rect& rect, bool urgent);
void invalidate(const QRegion &region);
@@ -68,6 +68,9 @@ public:
bool intercepts_sys_key() { return _key_interception;}
Point get_size() { return _size;}
bool has_monitor() { return _monitor != 0;}
+ void lock_size();
+ void unlock_size();
+ bool is_size_locked() { return _size_locked;}
void set_monitor(Monitor *monitor) { _monitor = monitor;}
Monitor* get_monitor() { return _monitor;}
RedWindow* get_window() { return &_window;}
@@ -154,7 +157,7 @@ private:
private:
Application& _owner;
int _id;
- int _refs;
+ AtomicCount _refs;
std::wstring _name;
RedWindow _window;
std::vector<ScreenLayer*> _layes;
@@ -167,6 +170,7 @@ private:
bool _periodic_update;
bool _key_interception;
bool _update_by_timer;
+ bool _size_locked;
int _forec_update_timer;
AutoRef<UpdateTimer> _update_timer;
RedDrawable* _composit_area;