summaryrefslogtreecommitdiffstats
path: root/client/x11
diff options
context:
space:
mode:
authorArnon Gilboa <agilboa@redhat.com>2009-12-30 13:41:58 +0200
committerYaniv Kamay <ykamay@redhat.com>2010-01-03 17:55:32 +0200
commit4202ee3945bdcbe78326562b49817c086dc67e18 (patch)
tree3243083507043f72924a7651c71d0a5af94167b6 /client/x11
parent8ce343daa08d2807428f71f552e22ab5319f8aea (diff)
downloadspice-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()
Diffstat (limited to 'client/x11')
-rw-r--r--client/x11/platform.cpp57
-rw-r--r--client/x11/red_window.cpp75
-rw-r--r--client/x11/red_window_p.h4
3 files changed, 77 insertions, 59 deletions
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;