Skip to content

Commit

Permalink
#41: send relative pointer position to the clients that are not movin…
Browse files Browse the repository at this point in the history
…g the mouse so they can display it

git-svn-id: https://xpra.org/svn/Xpra/trunk@14373 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Nov 1, 2016
1 parent 9884d37 commit 539526f
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 21 deletions.
17 changes: 16 additions & 1 deletion src/xpra/client/gl/gl_window_backing_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def get_fcolor(encoding):
GL_UNPACK_ROW_LENGTH, GL_UNPACK_ALIGNMENT, \
GL_TEXTURE_MAG_FILTER, GL_TEXTURE_MIN_FILTER, GL_NEAREST, \
GL_UNSIGNED_BYTE, GL_LUMINANCE, GL_LINEAR, \
GL_TEXTURE0, GL_TEXTURE1, GL_TEXTURE2, GL_QUADS, GL_POLYGON, GL_LINE_LOOP, GL_COLOR_BUFFER_BIT, \
GL_TEXTURE0, GL_TEXTURE1, GL_TEXTURE2, GL_QUADS, GL_POLYGON, GL_LINE_LOOP, GL_LINES, GL_COLOR_BUFFER_BIT, \
GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER, \
GL_DONT_CARE, GL_TRUE, GL_DEPTH_TEST, GL_SCISSOR_TEST, GL_LIGHTING, GL_DITHER, \
GL_RGB, GL_RGBA, GL_BGR, GL_BGRA, \
Expand Down Expand Up @@ -687,6 +687,21 @@ def do_present_fbo(self):
glVertex2i(px, py)
glEnd()

if self.pointer_overlay:
x, y, size, start_time = self.pointer_overlay
elapsed = time.time()-start_time
if elapsed<5:
alpha = max(0, (5.0-elapsed)/5.0)
glBegin(GL_LINES)
glColor4f(0, 0, 0, alpha)
glVertex2i(x-size, y)
glVertex2i(x+size, y)
glVertex2i(x, y-size)
glVertex2i(x, y+size)
glEnd()
else:
self.pointer_overlay = None

# Show the backbuffer on screen
self.gl_show(rect_count)
self.gl_frame_terminator()
Expand Down
16 changes: 15 additions & 1 deletion src/xpra/client/gl/gtk2/gl_client_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import gobject

from xpra.util import AdHocStruct
from xpra.client.gtk2.gtk2_window_base import GTK2WindowBase
from xpra.client.gl.gtk2.gl_window_backing import GLPixmapBacking

Expand Down Expand Up @@ -51,10 +52,23 @@ def spinner(self, ok):
b.paint_spinner = self.can_have_spinner() and not ok
log("spinner(%s) backing=%s, paint_screen=%s, paint_spinner=%s", ok, b._backing, b.paint_screen, b.paint_spinner)
if b._backing and b.paint_screen:
b.gl_expose_event(self._backing._backing, "spinner: fake event")
w, h = self.get_size()
self.queue_draw(0, 0, w, h)

def queue_draw(self, x, y, w, h):
b = self._backing
if not b:
return
if b._backing and b.paint_screen:
area = AdHocStruct()
area.x = x
area.y = y
area.width = w
area.height = h
event = AdHocStruct()
event.area = area
b.gl_expose_event(b._backing, event)

def do_expose_event(self, event):
log("GL do_expose_event(%s)", event)

Expand Down
11 changes: 8 additions & 3 deletions src/xpra/client/gl/gtk2/gl_window_backing.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,15 @@ def gl_expose_event(self, glarea=None, event=None):
if not self.paint_screen:
return
context = self.gl_context()
log("%s.gl_expose_event(%s, %s) context=%s", self, glarea, event, context)
if event and event.area:
area = event.area
rect = (area.x, area.y, area.width, area.height)
else:
w, h = self.size
rect = (0, 0, w, h)
log("%s.gl_expose_event(%s, %s) context=%s, area=%s", self, glarea, event, context, area)
if not context:
return
with context:
self.gl_init()
w, h = self.size
self.present_fbo(0, 0, w, h)
self.present_fbo(*rect)
27 changes: 23 additions & 4 deletions src/xpra/client/ui_client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def add_legacy_names(codecs):
MONITOR_CHANGE_REINIT = envint("XPRA_MONITOR_CHANGE_REINIT")

AV_SYNC_DELTA = envint("XPRA_AV_SYNC_DELTA")
MOUSE_ECHO = envbool("XPRA_MOUSE_ECHO")
MOUSE_SHOW = envbool("XPRA_MOUSE_SHOW", True)

PAINT_FAULT_RATE = envint("XPRA_PAINT_FAULT_INJECTION_RATE")
PAINT_FAULT_TELL = envbool("XPRA_PAINT_FAULT_INJECTION_TELL", True)
Expand Down Expand Up @@ -1406,7 +1406,7 @@ def make_hello(self):
"screen-scaling.enabled" : (self.xscale!=1 or self.yscale!=1),
"screen-scaling.values" : (int(1000*self.xscale), int(1000*self.yscale)),
#mouse and cursors:
"mouse.echo" : MOUSE_ECHO,
"mouse.show" : MOUSE_SHOW,
"mouse.initial-position" : self.get_mouse_position(),
"named_cursors" : False,
"cursors" : self.client_supports_cursors,
Expand Down Expand Up @@ -3082,8 +3082,27 @@ def _process_show_desktop(self, packet):


def _process_pointer_position(self, packet):
x, y = packet[1:3]
mouselog("process_pointer_position: %s - current position is %s", (x, y), self.get_mouse_position())
wid, x, y = packet[1:4]
if len(packet)>=6:
rx, ry = packet[4:6]
cx, cy = self.get_mouse_position()
size = 4
start_time = time.time()
mouselog("process_pointer_position: %i,%i (%i,%i relative to wid %i) - current position is %i,%i", x, y, rx, ry, wid, cx, cy)
for i,w in self._id_to_window.items():
if i==wid:
value = rx, ry, size, start_time
else:
value = None
prev = w._backing.pointer_overlay
if prev!=value:
b = w._backing
b.pointer_overlay = value
w.queue_draw(rx-size, ry-size, size*2, size*2)
#b.gl_expose_event(b._backing, "pointer: fake event")
if prev:
px, py, psize, _ = prev
w.queue_draw(px-psize, py-psize, psize*2, psize*2)


def _process_initiate_moveresize(self, packet):
Expand Down
1 change: 1 addition & 0 deletions src/xpra/client/window_backing_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def __init__(self, wid, window_alpha, idle_add):
self._csc_decoder = None
self._decoder_lock = Lock()
self._PIL_encodings = []
self.pointer_overlay = None
PIL = get_codec("dec_pillow")
if PIL:
self._PIL_encodings = PIL.get_encodings()
Expand Down
19 changes: 10 additions & 9 deletions src/xpra/server/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
elog = Logger("encoding")
soundlog = Logger("sound")
keylog = Logger("keyboard")
mouselog = Logger("mouse")
cursorlog = Logger("cursor")
metalog = Logger("metadata")
printlog = Logger("printing")
Expand Down Expand Up @@ -287,7 +288,7 @@ def __init__(self, protocol, disconnect_cb, idle_add, timeout_add, source_remove
self.mmap_size = 0
self.mmap_client_token = None #the token we write that the client may check
# mouse echo:
self.mouse_echo = False
self.mouse_show = False
self.mouse_last_position = None
# sound:
self.sound_properties = sound_properties
Expand Down Expand Up @@ -711,7 +712,7 @@ def parse_batch_int(value, varname):
self.send_bell = c.boolget("bell")
self.send_notifications = c.boolget("notifications")
self.randr_notify = c.boolget("randr_notify")
self.mouse_echo = c.boolget("mouse.echo")
self.mouse_show = c.boolget("mouse.show")
self.mouse_last_position = c.intpair("mouse.initial-position")
self.clipboard_enabled = c.boolget("clipboard", True)
self.clipboard_notifications = c.boolget("clipboard.notifications")
Expand Down Expand Up @@ -1309,13 +1310,13 @@ def get_keycode(self, client_keycode, keyname, modifiers):
return self.keyboard_config.get_keycode(client_keycode, keyname, modifiers)


def update_mouse(self, wid, x, y):
log("update_mouse(%s, %i, %i) current=%s", wid, x, y, self.mouse_last_position)
if not self.mouse_echo:
def update_mouse(self, wid, x, y, rx, ry):
mouselog("update_mouse(%s, %i, %i, %i, %i) current=%s", wid, x, y, rx, ry, self.mouse_last_position)
if not self.mouse_show:
return
if self.mouse_last_position!=(x,y):
self.mouse_last_position = (x, y)
self.send("pointer-position", x, y)
if self.mouse_last_position!=(x, y, rx, ry):
self.mouse_last_position = (x, y, rx, ry)
self.send("pointer-position", wid, x, y, rx, ry)

#
# Functions for interacting with the network layer:
Expand Down Expand Up @@ -1972,7 +1973,7 @@ def new_window(self, ptype, wid, window, x, y, w, h, client_properties):
else:
metalog("make_metadata(%s, %s, %s)=%s", wid, window, prop, v)
metadata.update(v)
log("new_window(%s, %s, %s, %s, %s, %s, %s, %s) metadata(%s)=%s", ptype, window, wid, x, y, w, h, client_properties, send_props, metadata)
log.warn("new_window(%s, %s, %s, %s, %s, %s, %s, %s) metadata(%s)=%s", ptype, window, wid, x, y, w, h, client_properties, send_props, metadata)
self.send(ptype, wid, x, y, w, h, metadata, client_properties or {})
if send_raw_icon:
self.send_window_icon(wid, window)
Expand Down
31 changes: 28 additions & 3 deletions src/xpra/x11/x11_server_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class X11ServerBase(GTKServerBase):
def __init__(self):
self.screen_number = gtk.gdk.display_get_default().get_default_screen().get_number()
self.root_window = gtk.gdk.get_default_root_window()
self.last_mouse_user = None
GTKServerBase.__init__(self)

def init(self, opts):
Expand Down Expand Up @@ -617,10 +618,32 @@ def do_xpra_cursor_event(self, event):
return False

def do_xpra_motion_event(self, event):
mouselog("motion event: %s", event)
wid = self._window_to_id.get(event.subwindow, 0)
mouselog("motion event: %s (last mouse user=%s)", event, self.last_mouse_user)
#find the window model for this gdk window:
wid = 0
model = None
window = event.subwindow
#TODO: find the gdk.Window without iterating over all of them:
for w,_wid in self._window_to_id.items():
if w.get_property("client-window")==window:
model = w
wid = _wid
break
for ss in self._server_sources.values():
ss.update_mouse(wid, event.x_root, event.y_root)
if self.last_mouse_user is None or self.last_mouse_user!=ss.uuid:
#we may adjust for window position differences
x = event.x_root
y = event.y_root
#relative to the model if we found it
if model:
wx, wy = model.get_geometry()[:2]
rx = x-wx
ry = y-wy
else:
assert wid==0
rx = x
ry = y
ss.update_mouse(wid, x, y, rx, ry)

def do_xpra_xkb_event(self, event):
#X11: XKBNotify
Expand Down Expand Up @@ -671,6 +694,8 @@ def do_process_mouse_common(self, proto, wid, pointer):
return
pos = self.root_window.get_pointer()[:2]
if pos!=pointer:
ss = self._server_sources.get(proto)
self.last_mouse_user = ss.uuid
with xswallow:
self._move_pointer(wid, pointer)

Expand Down

0 comments on commit 539526f

Please sign in to comment.