Skip to content

Commit

Permalink
better version of r18189: we define a new pseudo encoding called "def…
Browse files Browse the repository at this point in the history
…ault" and send a mostly empty packet when the client supports that

git-svn-id: https://xpra.org/svn/Xpra/trunk@18191 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Jan 29, 2018
1 parent 6cb71dd commit 293e392
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 19 deletions.
13 changes: 7 additions & 6 deletions src/xpra/client/ui_client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,7 @@ def get_cursor_encodings(self):
return e

def get_window_icon_encodings(self):
e = ["premult_argb32"]
e = ["premult_argb32", "default"]
if "png" in self.get_core_encodings():
e.append("png")
return e
Expand Down Expand Up @@ -3566,8 +3566,7 @@ def _process_window_metadata(self, packet):

def _process_window_icon(self, packet):
wid, w, h, coding, data = packet[1:6]
isdefault = len(packet)>=7 and packet[6]
img = self._window_icon_image(wid, w, h, coding, data, isdefault)
img = self._window_icon_image(wid, w, h, coding, data)
window = self._id_to_window.get(wid)
iconlog("_process_window_icon(%s, %s, %s, %s, %s bytes) image=%s, window=%s", wid, w, h, coding, len(data), img, window)
if window and img:
Expand Down Expand Up @@ -3610,13 +3609,15 @@ def set_tray_icon(self):
traylog("set_tray_icon() using default icon")
self.tray.set_icon()

def _window_icon_image(self, wid, width, height, coding, data, isdefault):
def _window_icon_image(self, wid, width, height, coding, data):
#convert the data into a pillow image,
#adding the icon overlay (if enabled)
from PIL import Image
coding = bytestostr(coding)
iconlog("%s.update_icon(%s, %s, %s, %s bytes) ICON_SHRINKAGE=%s, ICON_OVERLAY=%s", self, width, height, coding, len(data), ICON_SHRINKAGE, ICON_OVERLAY)
if coding == "premult_argb32": #we usually cannot do in-place and this is not performance critical
if coding=="default":
img = self.overlay_image
elif coding == "premult_argb32": #we usually cannot do in-place and this is not performance critical
from xpra.codecs.argb.argb import unpremultiply_argb #@UnresolvedImport
data = unpremultiply_argb(data)
rowstride = width*4
Expand All @@ -3629,7 +3630,7 @@ def _window_icon_image(self, wid, width, height, coding, data, isdefault):
has_alpha = img.mode=="RGBA"
rowstride = width * (3+int(has_alpha))
icon = img
if self.overlay_image and not isdefault:
if self.overlay_image and self.overlay_image!=img:
if ICON_SHRINKAGE>0 and ICON_SHRINKAGE<100:
#paste the application icon in the top-left corner,
#shrunk by ICON_SHRINKAGE pct
Expand Down
31 changes: 18 additions & 13 deletions src/xpra/server/window/window_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,14 +471,13 @@ def get_info(self):
info["pixel-format"] = self.pixel_format
idata = self.window_icon_data
if idata:
pixel_data, pixel_format, stride, w, h, isdefault = idata
pixel_data, pixel_format, stride, w, h = idata
info["icon"] = {
"pixel_format" : pixel_format,
"width" : w,
"height" : h,
"stride" : stride,
"bytes" : len(pixel_data),
"default" : bool(isdefault),
}
return info

Expand Down Expand Up @@ -590,33 +589,39 @@ def send_window_icon(self):
#try to load the icon for this class-instance from the theme:
surf = self.window.get_default_window_icon()
iconlog("send_window_icon window %s using default window icon=%s", self.window, surf)
#TODO: clients could expose a "default-icon" capabitlity,
# then we wouldn't even need to send any icon data, just the flag
isdefault = False
if not surf and self.window_icon_greedy:
#client does not set a default icon, so we must provide one every time
if not surf:
if not self.window_icon_greedy:
return
#"greedy": client does not set a default icon, so we must provide one every time
#to make sure that the window icon does get set to something
#(our icon is at least better than the window manager's default)
if "default" in self.window_icon_encodings:
#client will set the default itself,
#send a mostly empty packet:
packet = ("window-icon", self.wid, 0, 0, "default", "")
iconlog("queuing window icon update: %s", packet)
#this is cheap, so don't use the encode thread:
self.queue_packet(packet, wait_for_more=True)
return
surf = WindowSource.get_fallback_window_icon_surface()
isdefault = True
iconlog("using fallback window icon")
if surf:
if hasattr(surf, "get_pixels"):
#looks like a gdk.Pixbuf:
self.window_icon_data = (surf.get_pixels(), "RGBA", surf.get_rowstride(), surf.get_width(), surf.get_height(), isdefault)
self.window_icon_data = (surf.get_pixels(), "RGBA", surf.get_rowstride(), surf.get_width(), surf.get_height())
else:
#for debugging, save to a file so we can see it:
#surf.write_to_png("S-%s-%s.png" % (self.wid, int(time.time())))
#extract the data from the cairo surface
import cairo
assert surf.get_format() == cairo.FORMAT_ARGB32
self.window_icon_data = (surf.get_data(), "BGRA", surf.get_stride(), surf.get_width(), surf.get_height(), isdefault)
self.window_icon_data = (surf.get_data(), "BGRA", surf.get_stride(), surf.get_width(), surf.get_height())
if not self.send_window_icon_due:
self.send_window_icon_due = True
#call compress_clibboard via the work queue
#and delay sending it by a bit to allow basic icon batching:
delay = max(50, int(self.batch_config.delay))
iconlog("send_window_icon() window=%s, wid=%s, icon=%s, compression scheduled in %sms", self.window, self.wid, surf, delay)
iconlog("send_window_icon() window=%s, wid=%s, compression scheduled in %sms", self.window, self.wid, delay)
self.timeout_add(delay, self.call_in_encode_thread, True, self.compress_and_send_window_icon)

def compress_and_send_window_icon(self):
Expand All @@ -625,7 +630,7 @@ def compress_and_send_window_icon(self):
idata = self.window_icon_data
if not idata:
return
pixel_data, pixel_format, stride, w, h, isdefault = idata
pixel_data, pixel_format, stride, w, h = idata
PIL = get_codec("PIL")
max_w, max_h = self.window_icon_max_size
if stride!=w*4:
Expand Down Expand Up @@ -667,7 +672,7 @@ def compress_and_send_window_icon(self):
iconlog("cannot send window icon, supported encodings: %s", self.window_icon_encodings)
return
assert wrapper.datatype in ("premult_argb32", "png"), "invalid wrapper datatype %s" % wrapper.datatype
packet = ("window-icon", self.wid, w, h, wrapper.datatype, wrapper, isdefault)
packet = ("window-icon", self.wid, w, h, wrapper.datatype, wrapper)
iconlog("queuing window icon update: %s", packet)
self.queue_packet(packet, wait_for_more=True)

Expand Down

0 comments on commit 293e392

Please sign in to comment.