mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-08-07 14:50:22 +00:00
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.
This commit is contained in:
parent
941ba9bf5c
commit
cced1b1cff
@ -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;
|
||||
screen = _screens[id] = new RedScreen(*this, id, _title, size.x, size.y);
|
||||
|
||||
mon = get_monitor(id);
|
||||
capture = release_capture();
|
||||
screen->set_monitor(mon);
|
||||
position_screens();
|
||||
screen->show_full_screen();
|
||||
prepare_monitors();
|
||||
if (id != 0) {
|
||||
if (_full_screen) {
|
||||
bool capture;
|
||||
|
||||
if (capture) {
|
||||
_main_screen->activate();
|
||||
_main_screen->capture_mouse();
|
||||
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();
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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()) {
|
||||
|
||||
@ -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 ®ion);
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user