diff options
author | Arnon Gilboa <agilboa@redhat.com> | 2009-12-30 13:41:58 +0200 |
---|---|---|
committer | Yaniv Kamay <ykamay@redhat.com> | 2010-01-03 17:55:32 +0200 |
commit | 4202ee3945bdcbe78326562b49817c086dc67e18 (patch) | |
tree | 3243083507043f72924a7651c71d0a5af94167b6 | |
parent | 8ce343daa08d2807428f71f552e22ab5319f8aea (diff) | |
download | spice-4202ee3945bdcbe78326562b49817c086dc67e18.tar.gz spice-4202ee3945bdcbe78326562b49817c086dc67e18.tar.xz spice-4202ee3945bdcbe78326562b49817c086dc67e18.zip |
spice: position mouse in primary monitor center after full screen toggle
-move _focused & _pointer_in_window from RedWindow to RedWindow_p's
-move shadow focus & cursor handling to sync()
-add reset_cursor_pos() to Platform
-Monitor set_mode()/restore() use virtual do_set_mode()/do_restore()
-rw-r--r-- | client/monitor.cpp | 11 | ||||
-rw-r--r-- | client/monitor.h | 6 | ||||
-rw-r--r-- | client/platform.h | 2 | ||||
-rw-r--r-- | client/red_window.h | 2 | ||||
-rw-r--r-- | client/windows/platform.cpp | 33 | ||||
-rw-r--r-- | client/windows/red_window.cpp | 4 | ||||
-rw-r--r-- | client/windows/red_window_p.h | 2 | ||||
-rw-r--r-- | client/x11/platform.cpp | 57 | ||||
-rw-r--r-- | client/x11/red_window.cpp | 75 | ||||
-rw-r--r-- | client/x11/red_window_p.h | 4 |
10 files changed, 123 insertions, 73 deletions
diff --git a/client/monitor.cpp b/client/monitor.cpp index 85267693..d56cfadb 100644 --- a/client/monitor.cpp +++ b/client/monitor.cpp @@ -18,6 +18,7 @@ #include "common.h" #include "monitor.h" #include "debug.h" +#include "platform.h" uint32_t Monitor::self_monitors_change = 0; @@ -33,3 +34,13 @@ bool Monitor::is_self_change() return self_monitors_change != 0; } +void Monitor::set_mode(int width, int height) +{ + do_set_mode(width, height); + Platform::reset_cursor_pos(); +} +void Monitor::restore() +{ + do_restore(); + Platform::reset_cursor_pos(); +} diff --git a/client/monitor.h b/client/monitor.h index 59ec1e06..7a4ba3f2 100644 --- a/client/monitor.h +++ b/client/monitor.h @@ -29,8 +29,8 @@ public: void set_free() {_free = true;} void set_used() {_free = false;} - virtual void set_mode(int width, int height) = 0; - virtual void restore() = 0; + void set_mode(int width, int height); + void restore(); virtual int get_depth() = 0; virtual Point get_position() = 0; virtual Point get_size() const = 0; @@ -41,6 +41,8 @@ public: protected: virtual ~Monitor() {} + virtual void do_set_mode(int width, int height) = 0; + virtual void do_restore() = 0; private: int _id; diff --git a/client/platform.h b/client/platform.h index c32b8634..ff89181b 100644 --- a/client/platform.h +++ b/client/platform.h @@ -100,6 +100,8 @@ public: static uint32_t get_keyboard_modifiers(); + static void reset_cursor_pos(); + static LocalCursor* create_local_cursor(CursorData* cursor_data); static LocalCursor* create_inactive_cursor(); static LocalCursor* create_default_cursor(); diff --git a/client/red_window.h b/client/red_window.h index 6f51f70e..65d5efd5 100644 --- a/client/red_window.h +++ b/client/red_window.h @@ -105,8 +105,6 @@ private: Type _type; LocalCursor* _local_cursor; bool _cursor_visible; - bool _focused; - bool _pointer_in_window; bool _trace_key_interception; bool _key_interception_on; Menu* _menu; diff --git a/client/windows/platform.cpp b/client/windows/platform.cpp index 6d5deba5..2988827d 100644 --- a/client/windows/platform.cpp +++ b/client/windows/platform.cpp @@ -222,8 +222,6 @@ class WinMonitor: public Monitor { public: WinMonitor(int id, const wchar_t* name, const wchar_t* string); - virtual void set_mode(int width, int height); - virtual void restore(); virtual int get_depth() { return _depth;} virtual Point get_position(); virtual Point get_size() const { Point size = {_width, _height}; return size;} @@ -232,6 +230,8 @@ public: protected: virtual ~WinMonitor(); + virtual void do_set_mode(int width, int height); + virtual void do_restore(); private: void update_position(); @@ -261,7 +261,7 @@ WinMonitor::WinMonitor(int id, const wchar_t* name, const wchar_t* string) WinMonitor::~WinMonitor() { - restore(); + do_restore(); } void WinMonitor::update_position() @@ -357,7 +357,7 @@ bool WinMonitor::best_display_setting(uint32_t width, uint32_t height, uint32_t == DISP_CHANGE_SUCCESSFUL; } -void WinMonitor::set_mode(int width, int height) +void WinMonitor::do_set_mode(int width, int height) { update_position(); if (width == _width && height == _height) { @@ -375,31 +375,37 @@ void WinMonitor::set_mode(int width, int height) update_position(); } -void WinMonitor::restore() +void WinMonitor::do_restore() { if (_active) { _active = false; self_monitors_change++; ChangeDisplaySettingsEx(_dev_name.c_str(), NULL, NULL, 0, NULL); self_monitors_change--; + update_position(); } } static MonitorsList monitors; +static Monitor* primary_monitor = NULL; const MonitorsList& Platform::init_monitors() { ASSERT(monitors.empty()); int id = 0; + Monitor* mon; DISPLAY_DEVICE device_info; DWORD device_id = 0; device_info.cb = sizeof(device_info); while (EnumDisplayDevices(NULL, device_id, &device_info, 0)) { if ((device_info.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) && - !(device_info.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)) { - monitors.push_back(new WinMonitor(id++, device_info.DeviceName, - device_info.DeviceString)); + !(device_info.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)) { + mon = new WinMonitor(id++, device_info.DeviceName, device_info.DeviceString); + monitors.push_back(mon); + if (device_info.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) { + primary_monitor = mon; + } } device_id++; } @@ -408,6 +414,7 @@ const MonitorsList& Platform::init_monitors() void Platform::destroy_monitors() { + primary_monitor = NULL; while (!monitors.empty()) { Monitor* monitor = monitors.front(); monitors.pop_front(); @@ -502,6 +509,16 @@ uint32_t Platform::get_keyboard_modifiers() KEY_BIT(keymap, VK_RMENU, R_ALT_MODIFIER); } +void Platform::reset_cursor_pos() +{ + if (!primary_monitor) { + return; + } + Point pos = primary_monitor->get_position(); + Point size = primary_monitor->get_size(); + SetCursorPos(pos.x + size.x / 2, pos.y + size.y / 2); +} + class WinBaseLocalCursor: public LocalCursor { public: WinBaseLocalCursor() : _handle (0) {} diff --git a/client/windows/red_window.cpp b/client/windows/red_window.cpp index 554c1770..0d4c4a56 100644 --- a/client/windows/red_window.cpp +++ b/client/windows/red_window.cpp @@ -265,6 +265,8 @@ RedWindow_p::RedWindow_p() , _modal_refs (0) , _no_taskmgr_dll (NULL) , _no_taskmgr_hook (NULL) + , _focused (false) + , _pointer_in_window (false) , _minimized (false) , _valid_pos (false) , _sys_menu (NULL) @@ -344,8 +346,6 @@ RedWindow::RedWindow(RedWindow::Listener& listener, int screen_id) , _type (TYPE_NORMAL) , _local_cursor (NULL) , _cursor_visible (true) - , _focused (false) - , _pointer_in_window (false) , _trace_key_interception (false) , _key_interception_on (false) , _menu (NULL) diff --git a/client/windows/red_window_p.h b/client/windows/red_window_p.h index 4b5655ec..b35de571 100644 --- a/client/windows/red_window_p.h +++ b/client/windows/red_window_p.h @@ -56,6 +56,8 @@ protected: uint32_t _modal_refs; HMODULE _no_taskmgr_dll; HHOOK _no_taskmgr_hook; + bool _focused; + bool _pointer_in_window; bool _minimized; bool _valid_pos; int _x; diff --git a/client/x11/platform.cpp b/client/x11/platform.cpp index d00092be..a1c08ca8 100644 --- a/client/x11/platform.cpp +++ b/client/x11/platform.cpp @@ -491,18 +491,20 @@ public: monitors.push_back(this); } - virtual void set_mode(int width, int height) - { - _out_of_sync = width > get_width() || height > get_height(); - } - - virtual void restore() {} virtual int get_depth() { return XPlatform::get_vinfo()[0]->depth;} virtual Point get_position() { return XScreen::get_position();} virtual Point get_size() const { Point pt = {get_width(), get_height()}; return pt;} virtual bool is_out_of_sync() { return _out_of_sync;} virtual int get_screen_id() { return get_screen();} +protected: + virtual void do_set_mode(int width, int height) + { + _out_of_sync = width > get_width() || height > get_height(); + } + + virtual void do_restore() {} + private: bool _out_of_sync; }; @@ -513,14 +515,16 @@ public: virtual ~DynamicScreen(); void publish_monitors(MonitorsList& monitors); - virtual void set_mode(int width, int height); - virtual void restore(); virtual int get_depth() { return XPlatform::get_vinfo()[0]->depth;} virtual Point get_position() { return XScreen::get_position();} virtual Point get_size() const { Point pt = {get_width(), get_height()}; return pt;} virtual bool is_out_of_sync() { return _out_of_sync;} virtual int get_screen_id() { return get_screen();} +protected: + virtual void do_set_mode(int width, int height); + virtual void do_restore(); + private: bool set_screen_size(int size_index); @@ -573,7 +577,7 @@ public: } }; -void DynamicScreen::set_mode(int width, int height) +void DynamicScreen::do_set_mode(int width, int height) { int num_sizes; @@ -595,7 +599,7 @@ void DynamicScreen::set_mode(int width, int height) X_DEBUG_SYNC(get_display()); } -void DynamicScreen::restore() +void DynamicScreen::do_restore() { X_DEBUG_SYNC(get_display()); if (is_broken() || (get_width() == _saved_width && get_height() == _saved_height)) { @@ -689,8 +693,6 @@ public: XMonitor(MultyMonScreen& container, int id, RRCrtc crtc); virtual ~XMonitor(); - virtual void set_mode(int width, int height); - virtual void restore(); virtual int get_depth(); virtual Point get_position(); virtual Point get_size() const; @@ -719,6 +721,10 @@ public: static void inc_change_ref() { Monitor::self_monitors_change++;} static void dec_change_ref() { Monitor::self_monitors_change--;} +protected: + virtual void do_set_mode(int width, int height); + virtual void do_restore(); + private: void update_position(); bool finde_mode_in_outputs(RRMode mode, int start_index, XRRScreenResources* res); @@ -1657,7 +1663,7 @@ XRRModeInfo* XMonitor::find_mode(int width, int height, XRRScreenResources* res) return NULL; } -void XMonitor::set_mode(int width, int height) +void XMonitor::do_set_mode(int width, int height) { if (width == _size.x && height == _size.y) { _out_of_sync = false; @@ -1743,12 +1749,12 @@ bool XMonitor::position_changed() return _position.x != _saved_position.x || _position.y != _saved_position.y; } -void XMonitor::restore() +void XMonitor::do_restore() { if (!mode_changed()) { return; } - set_mode(_saved_size.x, _saved_size.y); + do_set_mode(_saved_size.x, _saved_size.y); } int XMonitor::get_depth() @@ -1831,6 +1837,7 @@ void XMonitor::set_mode(const XRRModeInfo& mode) #endif static MonitorsList monitors; +static Monitor* primary_monitor = NULL; typedef std::list<XScreen*> ScreenList; static ScreenList screens; @@ -1861,11 +1868,20 @@ const MonitorsList& Platform::init_monitors() for (; iter != screens.end(); iter++) { (*iter)->publish_monitors(monitors); } + MonitorsList::iterator mon_iter = monitors.begin(); + for (; mon_iter != monitors.end(); mon_iter++) { + Monitor *mon = *mon_iter; + if (mon->get_id() == 0) { + primary_monitor = mon; + break; + } + } return monitors; } void Platform::destroy_monitors() { + primary_monitor = NULL; monitors.clear(); while (!screens.empty()) { XScreen* screen = screens.front(); @@ -2257,6 +2273,17 @@ uint32_t Platform::get_keyboard_modifiers() key_bit(keymap, XK_Alt_R, R_ALT_MODIFIER); } +void Platform::reset_cursor_pos() +{ + if (!primary_monitor) { + return; + } + Point pos = primary_monitor->get_position(); + Point size = primary_monitor->get_size(); + Window root_window = RootWindow(x_display, DefaultScreen(x_display)); + XWarpPointer(x_display, None, root_window, 0, 0, 0, 0, pos.x + size.x / 2, pos.y + size.y / 2); +} + WaveRecordAbstract* Platform::create_recorder(RecordClient& client, uint32_t sampels_per_sec, uint32_t bits_per_sample, diff --git a/client/x11/red_window.cpp b/client/x11/red_window.cpp index 1647cd4d..7e25c608 100644 --- a/client/x11/red_window.cpp +++ b/client/x11/red_window.cpp @@ -844,6 +844,10 @@ void RedWindow_p::win_proc(XEvent& event) case EnterNotify: if (!red_window->_ignore_pointer) { red_window->on_pointer_enter(); + Point origin = red_window->get_origin(); + red_window->get_listener().on_mouse_motion(event.xcrossing.x - origin.x, + event.xcrossing.y - origin.y, + to_red_buttons_state(event.xcrossing.state)); } else { red_window->_shadow_pointer_state = true; memcpy(&red_window->_shadow_pointer_event, &event, sizeof(XEvent)); @@ -860,13 +864,35 @@ void RedWindow_p::win_proc(XEvent& event) } } -void RedWindow_p::sync() +void RedWindow_p::sync(bool shadowed) { + if (shadowed) { + _ignore_foucs = true; + _ignore_pointer = true; + _shadow_foucs_state = _focused; + _shadow_pointer_state = _pointer_in_window; + _shadow_focus_event.xany.serial = 0; + } XSync(x_display, False); XEvent event; while (XCheckWindowEvent(x_display, _win, ~long(0), &event)) { win_proc(event); } + if (!shadowed) { + return; + } + _ignore_foucs = false; + _ignore_pointer = false; + if (_shadow_foucs_state != _focused) { + DBG(0, "put back shadowed focus event"); + XPutBackEvent(x_display, &_shadow_focus_event); + } else if (_shadow_focus_event.xany.serial > 0) { + focus_serial = _shadow_focus_event.xany.serial; + } + if (_shadow_pointer_state != _pointer_in_window) { + DBG(0, "put back shadowed pointer event"); + XPutBackEvent(x_display, &_shadow_pointer_event); + } } void RedWindow_p::wait_for_reparent() @@ -977,7 +1003,9 @@ RedWindow_p::RedWindow_p() : _win (None) , _glcont_copy (NULL) , _icon (NULL) + , _focused (false) , _ignore_foucs (false) + , _pointer_in_window (false) , _ignore_pointer (false) { } @@ -1147,8 +1175,6 @@ RedWindow::RedWindow(RedWindow::Listener& listener, int screen) , _type (TYPE_NORMAL) , _local_cursor (NULL) , _cursor_visible (true) - , _focused (false) - , _pointer_in_window (false) , _trace_key_interception (false) , _key_interception_on (false) , _menu (NULL) @@ -1554,55 +1580,18 @@ void RedWindow::do_start_key_interception() // LeaveNotify and EnterNotify. ASSERT(_focused); - _ignore_foucs = true; - _ignore_pointer = true; - _shadow_foucs_state = true; - _shadow_pointer_state = true; - _shadow_focus_event.xany.serial = 0; XGrabKeyboard(x_display, _win, True, GrabModeAsync, GrabModeAsync, CurrentTime); - sync(); + sync(true); _listener.on_start_key_interception(); - _ignore_foucs = false; - _ignore_pointer = false; _key_interception_on = true; - if (!_shadow_foucs_state) { - DBG(0, "put back shadowed focus out"); - XPutBackEvent(x_display, &_shadow_focus_event); - } else if (_shadow_focus_event.xany.serial > 0) { - ASSERT(focus_window == this); - focus_serial = _shadow_focus_event.xany.serial; - } - - if (!_shadow_pointer_state) { - DBG(0, "put back shadowed pointer leave"); - XPutBackEvent(x_display, &_shadow_pointer_event); - } } void RedWindow::do_stop_key_interception() { - _ignore_foucs = true; - _ignore_pointer = true; - _shadow_foucs_state = _focused; - _shadow_pointer_state = _pointer_in_window; - _shadow_focus_event.xany.serial = 0; XUngrabKeyboard(x_display, CurrentTime); - sync(); + sync(true); _key_interception_on = false; _listener.on_stop_key_interception(); - _ignore_foucs = false; - _ignore_pointer = false; - if (_shadow_foucs_state != _focused) { - DBG(0, "put back shadowed focus event"); - XPutBackEvent(x_display, &_shadow_focus_event); - } else if (_shadow_focus_event.xany.serial > 0) { - focus_serial = _shadow_focus_event.xany.serial; - } - - if (_shadow_pointer_state != _pointer_in_window) { - DBG(0, "put back shadowed pointer event"); - XPutBackEvent(x_display, &_shadow_pointer_event); - } } void RedWindow::start_key_interception() @@ -1659,7 +1648,7 @@ void RedWindow::hide_cursor() void RedWindow::release_mouse() { XUngrabPointer(x_display, CurrentTime); - sync(); + sync(true); } void RedWindow::cupture_mouse() diff --git a/client/x11/red_window_p.h b/client/x11/red_window_p.h index 8b98b4a6..ab9ce048 100644 --- a/client/x11/red_window_p.h +++ b/client/x11/red_window_p.h @@ -41,7 +41,7 @@ public: void wait_for_reparent(); void wait_for_map(); void wait_for_unmap(); - void sync(); + void sync(bool shadowed = false); void set_visibale(bool vis) { _visibale = vis;} void move_to_current_desktop(); Window get_window() {return _win;} @@ -60,9 +60,11 @@ protected: Point _show_pos; GLXContext _glcont_copy; Icon* _icon; + bool _focused; bool _ignore_foucs; bool _shadow_foucs_state; XEvent _shadow_focus_event; + bool _pointer_in_window; bool _ignore_pointer; bool _shadow_pointer_state; XEvent _shadow_pointer_event; |