Hello community, here is the log from the commit of package xpra for openSUSE:Factory checked in at 2019-12-11 12:13:44 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/xpra (Old) and /work/SRC/openSUSE:Factory/.xpra.new.4691 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "xpra" Wed Dec 11 12:13:44 2019 rev:11 rq:755729 version:3.0.3 Changes: -------- --- /work/SRC/openSUSE:Factory/xpra/xpra.changes 2019-11-21 12:59:19.910515592 +0100 +++ /work/SRC/openSUSE:Factory/.xpra.new.4691/xpra.changes 2019-12-11 12:14:05.712528912 +0100 @@ -1,0 +2,39 @@ +Wed Dec 11 07:13:25 UTC 2019 - Luigi Baldoni <aloi...@gmx.com> + +- Update to version 3.0.3 + * fix clipboard synchronization with HTML5 client + * fix window repaints with GTK3 + * fix GDK scaling causing window painting issues (force off) + * fix slow repaint with OpenGL and combined updates (ie: + scrolling) + * fix missing video screen updates with 32-bit browsers: + disable video + * fix for X11 applications requesting invalid clipboard targets + * fix "xpra top" errors when the terminal window is too small + * fix blank xpra dialog windows when closed then shown again + (ie: server commands) + * fix compilation on non-i386 32-bit platforms + * fix platform query errors causing command failures + * fix Python2 builds: ignore GTK2 deprecation warnings + * fix X11 property synchronization with Python2 builds + * fix XSetClassHint call with Python 3 + * fix window move + resize shortcut + * fix ssh proxy options not preserved when loading session + files + * fix error and missing refresh after changing quality or + speed settings + * fix NVENC error when pynvml is not installed + * fix NVENC temporary failure retry code path + * fix DPI value from the command line with desktop-scaling + * fix typo in man page + * fix errors with some odd Python3 builds + (subprocess.getoutput) + * fix cursor packets missing encoding attribute + * fix notification error handling the speaker forwarding error + message + * fix incorrect and unhelpful message on connection error + * make it possible to disable colourspace synchronization + * show mdns status in xpra info + * support CUDA 10.2 + +------------------------------------------------------------------- Old: ---- xpra-3.0.2.tar.xz New: ---- xpra-3.0.3.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ xpra.spec ++++++ --- /var/tmp/diff_new_pack.d4TjNW/_old 2019-12-11 12:14:07.624528374 +0100 +++ /var/tmp/diff_new_pack.d4TjNW/_new 2019-12-11 12:14:07.628528373 +0100 @@ -1,7 +1,7 @@ # # spec file for package xpra # -# Copyright (c) 2019 SUSE LLC. +# Copyright (c) 2019 SUSE LLC # Copyright (c) 2012-2013 Pascal Bleser <pascal.ble...@opensuse.org> # # All modifications and additions to the file contributed by third parties @@ -19,7 +19,7 @@ %global __requires_exclude ^typelib\\(GtkosxApplication\\)|typelib\\(GdkGLExt\\)|typelib\\(GtkGLExt\\).*$ Name: xpra -Version: 3.0.2 +Version: 3.0.3 Release: 0 Summary: Remote display server for applications and desktops License: GPL-2.0-or-later AND BSD-3-Clause AND LGPL-3.0-or-later AND MIT ++++++ xpra-3.0.2.tar.xz -> xpra-3.0.3.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/NEWS new/xpra-3.0.3/NEWS --- old/xpra-3.0.2/NEWS 2019-11-05 18:31:07.000000000 +0100 +++ new/xpra-3.0.3/NEWS 2019-12-10 12:20:42.000000000 +0100 @@ -1,3 +1,46 @@ +v3.0.3 (2019-12-10) +====================== + -- fix clipboard synchronization with HTML5 client + -- fix window repaints with GTK3 + -- fix GDK scaling causing window painting issues (force off) + -- fix slow repaint with OpenGL and combined updates (ie: scrolling) + -- fix missing video screen updates with 32-bit browsers: disable video + -- fix for X11 applications requesting invalid clipboard targets + -- fix "xpra top" errors when the terminal window is too small + -- fix blank xpra dialog windows when closed then shown again (ie: server commands) + -- fix compilation on non-i386 32-bit platforms + -- fix platform query errors causing command failures + -- fix Python2 builds: ignore GTK2 deprecation warnings + -- fix X11 property synchronization with Python2 builds + -- fix XSetClassHint call with Python 3 + -- fix window move + resize shortcut + -- fix ssh proxy options not preserved when loading session files + -- fix focus of dialogs with MacOS clients (ie: SSH dialogs) + -- fix error and missing refresh after changing quality or speed settings + -- fix NVENC error when pynvml is not installed + -- fix NVENC temporary failure retry code path + -- fix SSH start for shadow and start-desktop subcommands from MacOS + -- fix fullscreen / maximized windows on MacOS + -- fix bogus screen dimensions with GTK3 on MacOS + -- fix client launcher helper script on MacOS + -- fix window resizing with OpenGL on MacOS + -- fix DPI value from the command line with desktop-scaling + -- fix typo in man page + -- fix errors with some odd Python3 builds (subprocess.getoutput) + -- fix cursor packets missing encoding attribute + -- fix dangling symlink in html5 client Fedora RPM package + -- fix notification error handling the speaker forwarding error message + -- fix incorrect and unhelpful message on connection error + -- fix openssl crypto DLL errors during MS Windows installation + -- prevent conflict with Fedora downstream packaging of xpra + -- make it possible to disable colourspace synchronization + -- show mdns status in xpra info + -- MacOS library updates (many, including Python 3.8.0) + -- support CUDA 10.2 + -- disable CSD on MS Windows (GTK3 CSD bug workaround) + -- re-enable OpenGL on MS Windows (was GTK3 bug) + + v3.0.2 (2019-11-05) ====================== -- fix clipboard synchronization issue with MS Windows clients properly diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/cups/xpraforwarder new/xpra-3.0.3/cups/xpraforwarder --- old/xpra-3.0.2/cups/xpraforwarder 2019-10-30 04:23:47.000000000 +0100 +++ new/xpra-3.0.3/cups/xpraforwarder 2019-11-18 16:50:49.000000000 +0100 @@ -42,7 +42,7 @@ from urllib.parse import urlparse, parse_qs -__version__ = "3.0.2" +__version__ = "3.0.3" #Writes a syslog entry (msg) at the default facility: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/etc/xpra/conf.d/40_client.conf.in new/xpra-3.0.3/etc/xpra/conf.d/40_client.conf.in --- old/xpra-3.0.2/etc/xpra/conf.d/40_client.conf.in 2019-11-05 18:31:07.000000000 +0100 +++ new/xpra-3.0.3/etc/xpra/conf.d/40_client.conf.in 2019-11-08 16:44:54.000000000 +0100 @@ -6,7 +6,7 @@ #opengl = no #opengl = gtk, native #opengl = auto -opengl = %(opengl)s +opengl = probe # How we handle server authentication requests: #challenge-handlers=none diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/html5/connect.html new/xpra-3.0.3/html5/connect.html --- old/xpra-3.0.2/html5/connect.html 2019-09-24 15:53:53.000000000 +0200 +++ new/xpra-3.0.3/html5/connect.html 2019-11-18 16:50:49.000000000 +0100 @@ -511,7 +511,10 @@ "sharing", "steal", "reconnect", "swap_keys", "video", "mediasource_video", "floating_menu", "autohide", "clock", "debug_main", "debug_keyboard", "debug_geometry", "debug_mouse", "debug_clipboard", "debug_draw", "debug_audio", "debug_network"]; - var default_on = ["steal", "clipboard", "printing", "file_transfer", "reconnect", "floating_menu", "clock", "exit_with_children", "exit_with_client", "video"]; + var default_on = ["steal", "clipboard", "printing", "file_transfer", "reconnect", "floating_menu", "clock", "exit_with_children", "exit_with_client"]; + if (Utilities.is_64bit()) { + default_on.push("video"); + } if (Utilities.isMacOS()) { default_on.push("swap_keys"); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/html5/index.html new/xpra-3.0.3/html5/index.html --- old/xpra-3.0.2/html5/index.html 2019-09-24 15:53:54.000000000 +0200 +++ new/xpra-3.0.3/html5/index.html 2019-11-18 16:50:49.000000000 +0100 @@ -212,12 +212,6 @@ var float_menu_padding = 20; var float_menu_width = (float_menu_item_size*4) + float_menu_padding; - // disable right click menu: - window.oncontextmenu = function(e) { - //showCustomMenu(); - return false; - } - var cdebug = function () { Utilities.clog.apply(Utilities, arguments); } @@ -430,7 +424,7 @@ var exit_with_children = getboolparam("exit_with_children", false); var exit_with_client = getboolparam("exit_with_client", false); var sharing = getboolparam("sharing", false); - var video = getboolparam("video", true); + var video = getboolparam("video", Utilities.is_64bit()); var mediasource_video = getboolparam("mediasource_video", false); var remote_logging = getboolparam("remote_logging", true); var insecure = getboolparam("insecure", false); @@ -932,6 +926,7 @@ var client = null; $(document).ready(function() { + clog("document is ready, browser is", navigator.platform, "64-bit:", Utilities.is_64bit()); var touchaction = getparam("touchaction") || "scroll"; touchaction_scroll = touchaction == "scroll"; set_touchaction(); @@ -1024,6 +1019,12 @@ $('#fullscreen_button').attr('data-icon', 'fullscreen'); } }); + // disable right click menu: + window.oncontextmenu = function(e) { + client._poll_clipboard(e); + //showCustomMenu(); + return false; + } }); </script> </body> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/html5/js/Client.js new/xpra-3.0.3/html5/js/Client.js --- old/xpra-3.0.2/html5/js/Client.js 2019-11-05 18:31:07.000000000 +0100 +++ new/xpra-3.0.3/html5/js/Client.js 2019-11-18 16:50:49.000000000 +0100 @@ -775,6 +775,8 @@ } } + this._poll_clipboard(event); + if (this.topwindow != null) { //send via a timer so we get a chance to capture the clipboard value, //before we send control-V to the server: @@ -1409,8 +1411,8 @@ XpraClient.prototype._poll_clipboard = function(e) { //see if the clipboard contents have changed: - this.debug("clipboard", "poll clipboard, navigator.clipboard=", navigator.clipboard); if (navigator.clipboard && navigator.clipboard.readText) { + this.debug("clipboard", "polling using", navigator.clipboard.readText); var client = this; //warning: this can take a while, //so we may send the click before the clipboard contents... @@ -1433,6 +1435,7 @@ if (!clipboardData) { clipboardData = window.clipboardData; if (!clipboardData) { + this.debug("clipboard", "polling: no data available") return; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/html5/js/Utilities.js new/xpra-3.0.3/html5/js/Utilities.js --- old/xpra-3.0.2/html5/js/Utilities.js 2019-10-30 04:23:47.000000000 +0100 +++ new/xpra-3.0.3/html5/js/Utilities.js 2019-11-18 16:50:49.000000000 +0100 @@ -10,7 +10,7 @@ 'use strict'; var Utilities = { - VERSION : "3.0.2", + VERSION : "3.0.3", exc : function() { console.error.apply(console, arguments); @@ -259,6 +259,26 @@ return navigator.userAgent.includes("MSIE") || navigator.userAgent.includes("Trident/"); }, + is_64bit : function() { + var _to_check = [] ; + if (window.navigator.cpuClass) + _to_check.push((window.navigator.cpuClass + "").toLowerCase()); + if (window.navigator.platform) + _to_check.push((window.navigator.platform + "").toLowerCase()); + if (navigator.userAgent) + _to_check.push((navigator.userAgent + "").toLowerCase()); + var _64bits_signatures = ["x86_64", "x86-64", "Win64", "x64;", "amd64", "AMD64", "WOW64", "x64_64", "ia64", "sparc64", "ppc64", "IRIX64"]; + var _i, _c; + for (_c=0; _c<_to_check.length; _c++) { + for (_i=0 ; _i<_64bits_signatures.length; _i++) { + if (_to_check[_c].indexOf(_64bits_signatures[_i].toLowerCase())!=-1) { + return true; + } + } + } + return false; + }, + getSimpleUserAgentString : function() { if (Utilities.isFirefox()) { return "Firefox"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/man/xpra.1 new/xpra-3.0.3/man/xpra.1 --- old/xpra-3.0.2/man/xpra.1 2019-09-24 15:53:55.000000000 +0200 +++ new/xpra-3.0.3/man/xpra.1 2019-11-26 16:58:06.000000000 +0100 @@ -779,7 +779,7 @@ \fB--ws-auth\fP=\fIMODULE\fP Just like the \fBauth\fP switch, except this one only applies to ws sockets: sockets defined using the \fBbind-ws\fP switch, -or TCP sockets upgraded to websockets. (if the \fBhtmlfP option is enabled). +or TCP sockets upgraded to websockets. (if the \fBhtml\fP option is enabled). .TP \fB--wss-auth\fP=\fIMODULE\fP Just like the \fBauth\fP switch, except this one only applies diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/scripts/xpra_launcher new/xpra-3.0.3/scripts/xpra_launcher --- old/xpra-3.0.2/scripts/xpra_launcher 2019-09-24 15:53:55.000000000 +0200 +++ new/xpra-3.0.3/scripts/xpra_launcher 2019-12-08 12:59:02.000000000 +0100 @@ -18,6 +18,7 @@ os.execvpe(py_exe, argv, env) sys.exit(1) +os.environ["GTK_CSD"] = "0" from xpra.platform import program_context with program_context("Xpra-Launcher", "Xpra Connection Launcher"): from xpra.client.gtk_base.client_launcher import do_main diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/setup.py new/xpra-3.0.3/setup.py --- old/xpra-3.0.2/setup.py 2019-11-05 18:31:07.000000000 +0100 +++ new/xpra-3.0.3/setup.py 2019-11-26 16:58:06.000000000 +0100 @@ -859,7 +859,6 @@ 'printing' : bstr(printing_ENABLED), 'dbus_control' : bstr(dbus_ENABLED), 'mmap' : bstr(True), - 'opengl' : "no" if WIN32 else "probe", } def convert_templates(subdirs): dirname = os.path.join(*(["etc", "xpra"] + subdirs)) @@ -1737,7 +1736,8 @@ if modules_ENABLED: add_packages("xpra.buffers") buffers_pkgconfig = pkgconfig(optimize=3) - if BITS==32: + import platform + if platform.machine()=="i386": #this may well be sub-optimal: add_to_keywords(buffers_pkgconfig, "extra_compile_args", "-mfpmath=387") if cython_ENABLED: @@ -2056,6 +2056,7 @@ nvcc_exe = "nvcc.exe" CUDA_DIR = os.environ.get("CUDA_DIR", "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA") path_options = [os.path.join(CUDA_DIR, x, "bin") for x in ( + "v10.2", "v10.1", "v10.0", "v9.2", @@ -2072,7 +2073,7 @@ break else: nvcc_exe = "nvcc" - for v in ("", "-10.1", "-10.0", "-9.2", "-9.1", "-9.0", "-8.0", "-7.5"): + for v in ("", "10.2", "-10.1", "-10.0", "-9.2", "-9.1", "-9.0", "-8.0", "-7.5"): path_options += ["/usr/local/cuda%s/bin" % v, "/opt/cuda%s/bin" % v] options = [os.path.join(x, nvcc_exe) for x in path_options] def which(cmd): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/setup_html5.py new/xpra-3.0.3/setup_html5.py --- old/xpra-3.0.2/setup_html5.py 2019-09-24 15:53:55.000000000 +0200 +++ new/xpra-3.0.3/setup_html5.py 2019-12-08 12:59:02.000000000 +0100 @@ -61,10 +61,12 @@ symlinks = { "jquery.js" : [ "/usr/share/javascript/jquery/jquery.js", + "/usr/share/javascript/jquery/latest/jquery.js", "/usr/share/javascript/jquery/3/jquery.js", ], "jquery-ui.js" : [ "/usr/share/javascript/jquery-ui/jquery-ui.js", + "/usr/share/javascript/jquery-ui/latest/jquery-ui.js", "/usr/share/javascript/jquery-ui/3/jquery-ui.js", ], } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/svn-info new/xpra-3.0.3/svn-info --- old/xpra-3.0.2/svn-info 2019-11-05 18:31:10.000000000 +0100 +++ new/xpra-3.0.3/svn-info 2019-12-10 18:47:53.000000000 +0100 @@ -4,10 +4,10 @@ Relative URL: ^/tags/v3.0.x/src Repository Root: file:///var/svn/repos/Xpra Repository UUID: 3bb7dfac-3a0b-4e04-842a-767bc560f471 -Revision: 24387 +Revision: 24692 Node Kind: directory Schedule: normal Last Changed Author: antoine -Last Changed Rev: 24387 -Last Changed Date: 2019-11-05 12:01:27 +0000 (Tue, 05 Nov 2019) +Last Changed Rev: 24688 +Last Changed Date: 2019-12-10 08:58:31 +0000 (Tue, 10 Dec 2019) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/svn-version new/xpra-3.0.3/svn-version --- old/xpra-3.0.2/svn-version 2019-11-05 18:31:10.000000000 +0100 +++ new/xpra-3.0.3/svn-version 2019-12-10 18:47:54.000000000 +0100 @@ -1 +1 @@ -24387 +24692 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/win32/BUILD_CUDA_KERNEL.BAT new/xpra-3.0.3/win32/BUILD_CUDA_KERNEL.BAT --- old/xpra-3.0.2/win32/BUILD_CUDA_KERNEL.BAT 2019-09-24 15:53:58.000000000 +0200 +++ new/xpra-3.0.3/win32/BUILD_CUDA_KERNEL.BAT 2019-11-26 16:58:06.000000000 +0100 @@ -5,7 +5,7 @@ SET CUDA_SRC=xpra\codecs\cuda_common\%KERNEL%.cu SET CUDA_BIN=xpra\codecs\cuda_common\%KERNEL%.fatbin -SET NVCC_DIR=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\bin\ +SET NVCC_DIR=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.2\bin\ SET NVCC=%NVCC_DIR%\nvcc.exe CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/win32/MINGW_BUILD.sh new/xpra-3.0.3/win32/MINGW_BUILD.sh --- old/xpra-3.0.2/win32/MINGW_BUILD.sh 2019-10-06 04:56:55.000000000 +0200 +++ new/xpra-3.0.3/win32/MINGW_BUILD.sh 2019-12-10 12:20:42.000000000 +0100 @@ -366,6 +366,11 @@ cp -fn "${MINGW_PREFIX}/bin/openssl.exe" "${DIST}/" #use the old filename so we don't have to change the xpra.iss and the setup.py build system: cp -fn "${MINGW_PREFIX}/ssl/openssl.cnf" "${DIST}/openssl.cfg" + if [ "${PYTHON_MAJOR_VERSION}" == "3" ]; then + #we need those libraries at the top level: + mv "${DIST}"/lib/libssl-*dll "${DIST}/" + mv "${DIST}"/lib/libcrypto-*dll "${DIST}/" + fi fi if [ "${DO_VERPATCH}" == "1" ]; then diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/win32/xpra.iss new/xpra-3.0.3/win32/xpra.iss --- old/xpra-3.0.2/win32/xpra.iss 2019-10-30 04:23:47.000000000 +0100 +++ new/xpra-3.0.3/win32/xpra.iss 2019-11-18 16:50:49.000000000 +0100 @@ -1,9 +1,9 @@ [Setup] AppName=Xpra AppId=Xpra_is1 -AppVersion=3.0.2 -AppVerName=Xpra 3.0.2 -UninstallDisplayName=Xpra 3.0.2 +AppVersion=3.0.3 +AppVerName=Xpra 3.0.3 +UninstallDisplayName=Xpra 3.0.3 AppPublisher=xpra.org AppPublisherURL=http:;xpra.org/ DefaultDirName={pf}\Xpra @@ -16,7 +16,7 @@ Compression=lzma2/max SolidCompression=yes AllowUNCPath=false -VersionInfoVersion=3.0.2 +VersionInfoVersion=3.0.3 VersionInfoCompany=xpra.org VersionInfoDescription=multi-platform screen and application forwarding system WizardImageFile=win32\xpra-logo.bmp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/__init__.py new/xpra-3.0.3/xpra/__init__.py --- old/xpra-3.0.2/xpra/__init__.py 2019-11-05 18:31:19.000000000 +0100 +++ new/xpra-3.0.3/xpra/__init__.py 2019-12-10 18:47:54.000000000 +0100 @@ -4,4 +4,4 @@ # Xpra is released under the terms of the GNU GPL v2, or, at your option, any # later version. See the file COPYING for details. -__version__ = "3.0.2" +__version__ = "3.0.3" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/client_base.py new/xpra-3.0.3/xpra/client/client_base.py --- old/xpra-3.0.2/xpra/client/client_base.py 2019-09-24 15:53:58.000000000 +0200 +++ new/xpra-3.0.3/xpra/client/client_base.py 2019-12-08 13:07:35.000000000 +0100 @@ -590,11 +590,11 @@ if p and p.input_raw_packetcount==0: props = p.get_info() c = props.get("compression", "unknown") - e = props.get("encoder", "unknown") + e = props.get("encoder", "rencode") netlog.error("Error: failed to receive anything, not an xpra server?") netlog.error(" could also be the wrong protocol, username, password or port") netlog.error(" or the session was not found") - if c!="unknown" or e!="unknown": + if c!="unknown" or e!="rencode": netlog.error(" or maybe this server does not support '%s' compression or '%s' packet encoding?", c, e) if self.exit_code is None: self.warn_and_quit(EXIT_CONNECTION_LOST, "Connection lost") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/client_window_base.py new/xpra-3.0.3/xpra/client/client_window_base.py --- old/xpra-3.0.2/xpra/client/client_window_base.py 2019-10-06 04:56:55.000000000 +0200 +++ new/xpra-3.0.3/xpra/client/client_window_base.py 2019-11-26 16:58:06.000000000 +0100 @@ -25,7 +25,6 @@ alphalog = Logger("alpha") -REPAINT_ALL = os.environ.get("XPRA_REPAINT_ALL", "") SIMULATE_MOUSE_DOWN = envbool("XPRA_SIMULATE_MOUSE_DOWN", True) PROPERTIES_DEBUG = [x.strip() for x in os.environ.get("XPRA_WINDOW_PROPERTIES_DEBUG", "").split(",")] AWT_DIALOG_WORKAROUND = envbool("XPRA_AWT_DIALOG_WORKAROUND", WIN32) @@ -76,6 +75,7 @@ self.button_state = {} self.pixel_depth = pixel_depth #0 for default self.window_offset = None #actual vs reported coordinates + self.pending_refresh = [] self.init_window(metadata) self.setup_window(bw, bh) @@ -649,27 +649,34 @@ from xpra.client.window_backing_base import fire_paint_callbacks fire_paint_callbacks(callbacks, -1, "no backing") return - def after_draw_refresh(success, message=""): - plog("after_draw_refresh(%s, %s) %sx%s at %sx%s encoding=%s, options=%s", - success, message, width, height, x, y, coding, options) - if success<=0: - return - backing = self._backing - if backing and (backing.draw_needs_refresh or REPAINT_ALL): - if REPAINT_ALL=="1" or self._client.xscale!=1 or self._client.yscale!=1 or is_Wayland(): - rw, rh = self.get_size() - rx, ry = 0, 0 - else: - rx, ry, rw, rh = self._client.srect(x, y, width, height) - #if self.window_offset: - # rx -= self.window_offset[0] - # ry -= self.window_offset[1] - self.idle_add(self.queue_draw_area, rx, ry, rw, rh) #only register this callback if we actually need it: if backing.draw_needs_refresh: - callbacks.append(after_draw_refresh) + if not backing.repaint_all: + self.pending_refresh.append((x, y, width, height)) + if options.intget("flush", 0)==0: + callbacks.append(self.after_draw_refresh) backing.draw_region(x, y, width, height, coding, img_data, rowstride, options, callbacks) + def after_draw_refresh(self, success, message=""): + plog("after_draw_refresh(%s, %s) pending_refresh=%s", + success, message, self.pending_refresh) + backing = self._backing + if not backing: + return + if backing.repaint_all or self._client.xscale!=1 or self._client.yscale!=1 or is_Wayland(): + #easy: just repaint the whole window: + rw, rh = self.get_size() + self.idle_add(self.queue_draw_area, 0, 0, rw, rh) + return + pr = self.pending_refresh + self.pending_refresh = [] + for x, y, w, h in pr: + rx, ry, rw, rh = self._client.srect(x, y, w, h) + #if self.window_offset: + # rx -= self.window_offset[0] + # ry -= self.window_offset[1] + self.idle_add(self.queue_draw_area, rx, ry, rw, rh) + def eos(self): """ Note: this runs from the draw thread (not UI thread) """ backing = self._backing diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/gl/gl_window_backing_base.py new/xpra-3.0.3/xpra/client/gl/gl_window_backing_base.py --- old/xpra-3.0.2/xpra/client/gl/gl_window_backing_base.py 2019-11-05 18:31:07.000000000 +0100 +++ new/xpra-3.0.3/xpra/client/gl/gl_window_backing_base.py 2019-12-08 12:59:02.000000000 +0100 @@ -76,10 +76,10 @@ JPEG_YUV = envbool("XPRA_JPEG_YUV", True) WEBP_YUV = envbool("XPRA_WEBP_YUV", True) FORCE_CLONE = envbool("XPRA_OPENGL_FORCE_CLONE", False) -DRAW_REFRESH = envbool("XPRA_OPENGL_DRAW_REFRESH", PYTHON3) +DRAW_REFRESH = envbool("XPRA_OPENGL_DRAW_REFRESH", True) FBO_RESIZE = envbool("XPRA_OPENGL_FBO_RESIZE", True) FBO_RESIZE_DELAY = envint("XPRA_OPENGL_FBO_RESIZE_DELAY", 50) -CONTEXT_REINIT = envbool("XPRA_OPENGL_CONTEXT_REINIT", OSX) +CONTEXT_REINIT = envbool("XPRA_OPENGL_CONTEXT_REINIT", False) CURSOR_IDLE_TIMEOUT = envint("XPRA_CURSOR_IDLE_TIMEOUT", 6) TEXTURE_CURSOR = envbool("XPRA_OPENGL_TEXTURE_CURSOR", True) @@ -255,6 +255,10 @@ self.bit_depth = self.get_bit_depth(pixel_depth) self.init_formats() self.draw_needs_refresh = DRAW_REFRESH + #the correct check would be this: + #self.repaint_all = self.is_double_buffered() or bw!=ww or bh!=wh + #but we're meant to be using double-buffered everywhere, so don't bother: + self.repaint_all = True self._backing.show() def init_gl_config(self, window_alpha): @@ -347,6 +351,7 @@ #and then doing the gl_init() call but without initializing the offscreen fbo. sx, sy, dx, dy, w, h = self.gravity_copy_coords(oldw, oldh, bw, bh) with context: + context.update_geometry() #invert Y coordinates for OpenGL: sy = (oldh-h)-sy dy = (bh-h)-dy @@ -630,7 +635,8 @@ glBindTexture(target, 0) glDisable(target) fire_paint_callbacks(callbacks, True) - self.present_fbo(0, 0, bw, bh, flush) + if not self.draw_needs_refresh: + self.present_fbo(0, 0, bw, bh, flush) def copy_fbo(self, w, h, sx=0, sy=0, dx=0, dy=0): #copy from offscreen to tmp: @@ -1068,7 +1074,8 @@ glDisable(target) self.paint_box(options.strget("encoding"), options.intget("delta", -1)>=0, x, y, width, height) # Present update to screen - self.present_fbo(x, y, width, height, options.intget("flush", 0)) + if not self.draw_needs_refresh: + self.present_fbo(x, y, width, height, options.intget("flush", 0)) # present_fbo has reset state already fire_paint_callbacks(callbacks) return @@ -1122,7 +1129,8 @@ self.paint_box(encoding, False, x, y, width, height) fire_paint_callbacks(callbacks, True) # Present it on screen - self.present_fbo(x, y, width, height, flush) + if not self.draw_needs_refresh: + self.present_fbo(x, y, width, height, flush) img.free() return except GLError as e: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/gtk_base/bug_report.py new/xpra-3.0.3/xpra/client/gtk_base/bug_report.py --- old/xpra-3.0.2/xpra/client/gtk_base/bug_report.py 2019-09-24 15:53:58.000000000 +0200 +++ new/xpra-3.0.3/xpra/client/gtk_base/bug_report.py 2019-12-08 12:59:03.000000000 +0100 @@ -40,7 +40,7 @@ def setup_window(self): self.window = gtk.Window() window_defaults(self.window) - self.window.connect("destroy", self.close) + self.window.connect("delete-event", self.close) self.window.set_default_size(400, 300) self.window.set_title("Xpra Bug Report") @@ -241,6 +241,7 @@ log("close%s", args) self.hide() self.window = None + return True def destroy(self, *args): log("destroy%s", args) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/gtk_base/client_launcher.py new/xpra-3.0.3/xpra/client/gtk_base/client_launcher.py --- old/xpra-3.0.2/xpra/client/gtk_base/client_launcher.py 2019-10-07 15:47:58.000000000 +0200 +++ new/xpra-3.0.3/xpra/client/gtk_base/client_launcher.py 2019-12-08 12:59:03.000000000 +0100 @@ -191,7 +191,7 @@ def do_create_window(self): self.window = gtk.Window() window_defaults(self.window) - self.window.connect("destroy", self.destroy) + self.window.connect("delete-event", self.destroy) self.window.set_default_size(400, 260) self.window.set_title("Xpra Launcher") @@ -648,10 +648,16 @@ # sshpass cannot do different username/passwords for proxy and destination if not sshpass: self.check_boxes_hbox.show() + p = self.password_entry.get_text() + pp = self.proxy_password_entry.get_text() + u = self.username_entry.get_text() + pu = self.proxy_username_entry.get_text() else: self.check_boxes_hbox.hide() - self.password_scb.set_active(True) - self.username_scb.set_active(True) + p = pp = None + u = pu = None + self.password_scb.set_active(p==pp) + self.username_scb.set_active(u==pu) else: self.password_hbox.hide() if sshtossh: @@ -1040,9 +1046,6 @@ #then select it in the combo: if index>=0: self.encoding_combo.set_history(index) - self.username_entry.set_text(self.config.username) - self.password_entry.set_text(self.config.password) - self.host_entry.set_text(self.config.host) def get_port(vstr, default_port=""): try: iport = int(vstr) @@ -1060,11 +1063,20 @@ #proxy bits: self.proxy_host_entry.set_text(self.config.proxy_host) self.proxy_port_entry.set_text(get_port(self.config.proxy_port)) - self.proxy_username_entry.set_text(self.config.proxy_username) - self.proxy_password_entry.set_text(self.config.proxy_password) + username = self.config.username + proxy_username = self.config.proxy_username + self.username_scb.set_active(username==proxy_username) + self.proxy_username_entry.set_text(proxy_username) + password = self.config.password + proxy_password = self.config.proxy_password + self.password_scb.set_active(password==proxy_password) + self.proxy_password_entry.set_text(proxy_password) if self.is_putty: self.proxy_key_entry.set_text(self.config.proxy_key) self.sharing.set_active(bool(self.config.sharing)) + self.username_entry.set_text(username) + self.password_entry.set_text(password) + self.host_entry.set_text(self.config.host) def close_window(self, *_args): w = self.window @@ -1078,6 +1090,7 @@ self.clean_client() self.close_window() gtk_main_quit_really() + return False def update_options_from_URL(self, url): from xpra.scripts.parsing import parse_URL @@ -1217,7 +1230,7 @@ app.reset_errors() if not app.config.autoconnect or app.config.debug: if OSX and not has_file: - from xpra.platform.darwin.gui import wait_for_open_handlers, show_with_focus_workaround + from xpra.platform.darwin.gui import wait_for_open_handlers, force_focus def open_file(filename): log("open_file(%s)", filename) app.update_options_from_file(filename) @@ -1229,7 +1242,8 @@ app.__osx_open_signal = True glib.idle_add(app.do_connect) else: - show_with_focus_workaround(app.show) + force_focus() + app.show() def open_URL(url): log("open_URL(%s)", url) app.__osx_open_signal = True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/gtk_base/confirm_dialog.py new/xpra-3.0.3/xpra/client/gtk_base/confirm_dialog.py --- old/xpra-3.0.2/xpra/client/gtk_base/confirm_dialog.py 2019-09-24 15:53:58.000000000 +0200 +++ new/xpra-3.0.3/xpra/client/gtk_base/confirm_dialog.py 2019-12-10 12:20:42.000000000 +0100 @@ -17,6 +17,7 @@ window_defaults, color_parse, is_gtk3, WIN_POS_CENTER, WINDOW_POPUP, STATE_NORMAL, ) +from xpra.platform.gui import force_focus from xpra.platform.paths import get_icon_dir from xpra.os_util import get_util_logger @@ -36,7 +37,7 @@ self.window = gtk.Window(WINDOW_POPUP) window_defaults(self.window) self.window.set_position(WIN_POS_CENTER) - self.window.connect("destroy", self.quit) + self.window.connect("delete-event", self.quit) self.window.set_default_size(400, 150) self.window.set_title(title) #self.window.set_modal(True) @@ -124,6 +125,7 @@ log("quit%s", args) self.destroy() gtk.main_quit() + return True def get_icon(self, icon_name): @@ -164,6 +166,7 @@ app = ConfirmDialogWindow(title, prompt, info, icon, buttons) register_os_signals(app.quit) gui_ready() + force_focus() app.show() return app.run() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/gtk_base/gtk_client_window_base.py new/xpra-3.0.3/xpra/client/gtk_base/gtk_client_window_base.py --- old/xpra-3.0.2/xpra/client/gtk_base/gtk_client_window_base.py 2019-10-01 07:09:12.000000000 +0200 +++ new/xpra-3.0.3/xpra/client/gtk_base/gtk_client_window_base.py 2019-12-08 12:59:03.000000000 +0100 @@ -12,7 +12,7 @@ except ImportError: from urllib.parse import unquote #python3 @Reimport @UnresolvedImport -from xpra.os_util import bytestostr, is_X11, monotonic_time, WIN32, OSX, POSIX, PYTHON3 +from xpra.os_util import bytestostr, strtobytes, is_X11, monotonic_time, WIN32, OSX, POSIX, PYTHON3, PYTHON2 from xpra.util import ( AdHocStruct, typedict, envint, envbool, nonl, csv, first_time, WORKSPACE_UNSET, WORKSPACE_ALL, WORKSPACE_NAMES, MOVERESIZE_DIRECTION_STRING, SOURCE_INDICATION_STRING, @@ -937,6 +937,8 @@ dtype = bytestostr(dtype) if dtype=="latin1": value = bytestostr(value) + if PYTHON2: + value = unicode(value) prop_set(gdk_window, prop_name, dtype, value) def set_class_instance(self, wmclass_name, wmclass_class): @@ -948,7 +950,7 @@ elif HAS_X11_BINDINGS: xid = get_xwindow(self.get_window()) with xlog: - X11Window.setClassHint(xid, wmclass_class, wmclass_name) + X11Window.setClassHint(xid, strtobytes(wmclass_class), strtobytes(wmclass_name)) log("XSetClassHint(%s, %s) done", wmclass_class, wmclass_name) def set_shape(self, shape): @@ -1915,8 +1917,8 @@ y += self.window_offset[1] #TODO: check this doesn't move it off-screen! self._resize_counter = resize_counter - window = self.get_window() - if window.get_position()==(x, y): + wx, wy = self.get_drawing_area_geometry()[:2] + if (wx, wy)==(x, y): #same location, just resize: if self._size==(w, h): geomlog("window unchanged") @@ -1930,6 +1932,7 @@ geomlog("window was not realized yet") self.realize() #adjust for window frame: + window = self.get_window() ox, oy = window.get_origin()[-2:] rx, ry = window.get_root_origin() ax = x - (ox - rx) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/gtk_base/open_requests.py new/xpra-3.0.3/xpra/client/gtk_base/open_requests.py --- old/xpra-3.0.2/xpra/client/gtk_base/open_requests.py 2019-09-24 15:53:59.000000000 +0200 +++ new/xpra-3.0.3/xpra/client/gtk_base/open_requests.py 2019-12-08 12:59:03.000000000 +0100 @@ -46,7 +46,7 @@ self.expire_labels = {} self.window = gtk.Window() window_defaults(self.window) - self.window.connect("destroy", self.close) + self.window.connect("delete-event", self.close) self.window.set_default_size(400, 150) self.window.set_title("Transfers") @@ -199,6 +199,7 @@ def close(self, *args): log("close%s", args) self.hide() + return True def destroy(self, *args): log("destroy%s", args) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/gtk_base/pass_dialog.py new/xpra-3.0.3/xpra/client/gtk_base/pass_dialog.py --- old/xpra-3.0.2/xpra/client/gtk_base/pass_dialog.py 2019-09-24 15:53:59.000000000 +0200 +++ new/xpra-3.0.3/xpra/client/gtk_base/pass_dialog.py 2019-12-10 12:20:42.000000000 +0100 @@ -12,6 +12,7 @@ import_gtk, import_pango, import_glib, register_os_signals, ) +from xpra.platform.gui import force_focus from xpra.os_util import get_util_logger from xpra.gtk_common.gtk_util import ( gtk_main, add_close_accel, pixbuf_new_from_file, window_defaults, @@ -35,7 +36,7 @@ self.window = gtk.Window(WINDOW_TOPLEVEL) window_defaults(self.window) self.window.set_position(WIN_POS_CENTER) - self.window.connect("destroy", self.quit) + self.window.connect("delete-event", self.quit) self.window.set_default_size(400, 150) self.window.set_title(title) self.window.set_modal(True) @@ -99,8 +100,11 @@ def show(self): log("show()") self.window.show_all() - glib.idle_add(self.window.present) - glib.idle_add(self.password_input.grab_focus) + def show(): + force_focus() + self.present() + self.password_input.grab_focus() + glib.idle_add(show) def destroy(self, *args): log("destroy%s", args) @@ -118,6 +122,7 @@ log("quit%s", args) self.destroy() gtk.main_quit() + return True def activate(self, *args): log("activate%s", args) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/gtk_base/server_commands.py new/xpra-3.0.3/xpra/client/gtk_base/server_commands.py --- old/xpra-3.0.2/xpra/client/gtk_base/server_commands.py 2019-09-24 15:53:59.000000000 +0200 +++ new/xpra-3.0.3/xpra/client/gtk_base/server_commands.py 2019-12-08 12:59:03.000000000 +0100 @@ -46,7 +46,7 @@ self.table = None self.window = gtk.Window() window_defaults(self.window) - self.window.connect("destroy", self.close) + self.window.connect("delete-event", self.close) self.window.set_default_size(400, 150) self.window.set_title("Server Commands") @@ -191,6 +191,7 @@ def close(self, *args): log("close%s", args) self.hide() + return True def destroy(self, *args): log("destroy%s", args) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/gtk_base/sessions_gui.py new/xpra-3.0.3/xpra/client/gtk_base/sessions_gui.py --- old/xpra-3.0.2/xpra/client/gtk_base/sessions_gui.py 2019-09-24 15:53:59.000000000 +0200 +++ new/xpra-3.0.3/xpra/client/gtk_base/sessions_gui.py 2019-12-08 12:59:03.000000000 +0100 @@ -12,6 +12,7 @@ from xpra.platform.paths import get_icon_dir, get_xpra_command, get_nodock_command from xpra.platform.dotxpra import DotXpra +from xpra.platform.gui import force_focus from xpra.child_reaper import getChildReaper from xpra.exit_codes import EXIT_STR from xpra.gtk_common.gtk_util import ( @@ -103,6 +104,13 @@ self.vbox.show() self.show() + def show(self): + self.show_all() + def show(): + force_focus() + self.present() + glib.idle_add(show) + def quit(self, *args): log("quit%s", args) self.do_quit() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/gtk_base/start_new_command.py new/xpra-3.0.3/xpra/client/gtk_base/start_new_command.py --- old/xpra-3.0.2/xpra/client/gtk_base/start_new_command.py 2019-09-24 15:53:59.000000000 +0200 +++ new/xpra-3.0.3/xpra/client/gtk_base/start_new_command.py 2019-12-08 12:59:03.000000000 +0100 @@ -44,7 +44,7 @@ self.xdg_menu = typedict(xdg_menu or {}) self.window = gtk.Window() window_defaults(self.window) - self.window.connect("destroy", self.close) + self.window.connect("delete-event", self.close) self.window.set_default_size(400, 150) self.window.set_title("Start New Command") @@ -56,6 +56,7 @@ vbox = gtk.VBox(False, 0) vbox.set_spacing(0) + self.entry = None if xdg_menu: # or use menus if we have xdg data: hbox = gtk.HBox(False, 20) @@ -135,7 +136,7 @@ category = self.category_combo.get_active_text() entries = typedict(self.xdg_menu.dictget(category.encode("utf-8"), {})).dictget("Entries", {}) log("command_changed(%s) category=%s, entries=%s", args, category, entries) - if entries: + if entries and self.entry: command_name = self.command_combo.get_active_text() command_props = typedict(entries).dictget(command_name.encode("utf-8"), {}) log("command properties=%s", command_props) @@ -155,6 +156,7 @@ def close(self, *args): log("close%s", args) self.hide() + return True def destroy(self, *args): log("destroy%s", args) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/gtk_base/update_status.py new/xpra-3.0.3/xpra/client/gtk_base/update_status.py --- old/xpra-3.0.2/xpra/client/gtk_base/update_status.py 2019-09-24 15:53:59.000000000 +0200 +++ new/xpra-3.0.3/xpra/client/gtk_base/update_status.py 2019-12-08 12:59:03.000000000 +0100 @@ -8,7 +8,7 @@ import os.path import sys -from xpra.platform.gui import init as gui_init +from xpra.platform.gui import init as gui_init, force_focus from xpra.gtk_common.gtk_util import ( gtk_main, add_close_accel, scaled_image, pixbuf_new_from_file, window_defaults, WIN_POS_CENTER, @@ -38,7 +38,7 @@ def __init__(self): self.window = gtk.Window() window_defaults(self.window) - self.window.connect("destroy", self.close) + self.window.connect("delete-event", self.close) self.window.set_default_size(400, 200) self.window.set_title("Xpra Version Check") @@ -112,8 +112,11 @@ def show(self): log("show()") - self.window.show() - self.window.present() + def show(): + force_focus() + self.window.show() + self.window.present() + glib.idle_add(show) def hide(self): log("hide()") @@ -122,6 +125,7 @@ def close(self, *args): log("close%s", args) self.hide() + return True def destroy(self, *args): log("destroy%s", args) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/mixins/audio.py new/xpra-3.0.3/xpra/client/mixins/audio.py --- old/xpra-3.0.2/xpra/client/mixins/audio.py 2019-09-24 15:53:59.000000000 +0200 +++ new/xpra-3.0.3/xpra/client/mixins/audio.py 2019-12-08 12:59:03.000000000 +0100 @@ -429,9 +429,10 @@ if sound_sink!=self.sound_sink: log("sound_sink_error(%s, %s) not the current sink, ignoring it", sound_sink, error) return - self.may_notify_audio("Speaker forwarding error", error) + estr = bytestostr(error).replace("gst-resource-error-quark: ", "") + self.may_notify_audio("Speaker forwarding error", estr) log.warn("Error: stopping speaker:") - log.warn(" %s", bytestostr(error).replace("gst-resource-error-quark: ", "")) + log.warn(" %s", estr) self.stop_receiving_sound() def sound_process_stopped(self, sound_sink, *args): if self.exit_code is not None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/mixins/display.py new/xpra-3.0.3/xpra/client/mixins/display.py --- old/xpra-3.0.2/xpra/client/mixins/display.py 2019-09-24 15:53:59.000000000 +0200 +++ new/xpra-3.0.3/xpra/client/mixins/display.py 2019-12-08 12:59:03.000000000 +0100 @@ -14,7 +14,7 @@ from xpra.scripts.config import FALSE_OPTIONS from xpra.os_util import monotonic_time from xpra.util import ( - iround, envint, envfloat, log_screen_sizes, engs, flatten_dict, + iround, envint, envfloat, envbool, log_screen_sizes, engs, flatten_dict, XPRA_SCALING_NOTIFICATION_ID, ) from xpra.client.mixins.stub_client_mixin import StubClientMixin @@ -31,6 +31,7 @@ MAX_SCALING = envfloat("XPRA_MAX_SCALING", "8") SCALING_OPTIONS = [float(x) for x in os.environ.get("XPRA_TRAY_SCALING_OPTIONS", "0.25,0.5,0.666,1,1.25,1.5,2.0,3.0,4.0,5.0").split(",") if float(x)>=MIN_SCALING and float(x)<=MAX_SCALING] SCALING_EMBARGO_TIME = int(os.environ.get("XPRA_SCALING_EMBARGO_TIME", "1000"))/1000.0 +SYNC_ICC = envbool("XPRA_SYNC_ICC", True) def r4cmp(v, rounding=1000.0): #ignore small differences in floats for scale values @@ -142,7 +143,7 @@ dpi = 0 if self.dpi>0: #scale it: - dpi = self.cx(self.cy(self.dpi)) + dpi = self.cx(self.cy(self.dpi*2)) else: #not supplied, use platform detection code: #platforms may also provide per-axis dpi (later win32 versions do) @@ -170,14 +171,18 @@ } def get_screen_caps(self): - return { + caps = { "antialias" : get_antialias_info(), - "icc" : self.get_icc_info(), - "display-icc" : self.get_display_icc_info(), "cursor" : { "size" : int(2*get_cursor_size()/(self.xscale+self.yscale)), }, } + if SYNC_ICC: + caps.update({ + "icc" : self.get_icc_info(), + "display-icc" : self.get_display_icc_info(), + }) + return caps #this is the format we should be moving towards #with proper namespace: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/mixins/window_manager.py new/xpra-3.0.3/xpra/client/mixins/window_manager.py --- old/xpra-3.0.2/xpra/client/mixins/window_manager.py 2019-10-28 16:04:05.000000000 +0100 +++ new/xpra-3.0.3/xpra/client/mixins/window_manager.py 2019-11-21 08:29:31.000000000 +0100 @@ -1308,10 +1308,14 @@ if self._suspended_at>0: elapsed = max(0, time()-self._suspended_at) self._suspended_at = 0 + self.send_refresh_all() + if elapsed<1: + #not really suspended + #happens on macos when switching workspace! + return delta = datetime.timedelta(seconds=int(elapsed)) log.info("system resumed, was suspended for %s", str(delta).lstrip("0:")) #this will reset the refresh rate too: - self.send_refresh_all() if self.opengl_enabled: #with opengl, the buffers sometimes contain garbage after resuming, #this should create new backing buffers: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/top_client.py new/xpra-3.0.3/xpra/client/top_client.py --- old/xpra-3.0.2/xpra/client/top_client.py 2019-10-20 14:13:42.000000000 +0200 +++ new/xpra-3.0.3/xpra/client/top_client.py 2019-11-18 16:50:49.000000000 +0100 @@ -7,7 +7,7 @@ from datetime import datetime, timedelta from xpra import __version__ -from xpra.util import typedict, std, envint, csv +from xpra.util import typedict, std, envint, csv, engs from xpra.os_util import platform_name, bytestostr from xpra.client.gobject_client_base import MonitorXpraClient from xpra.log import Logger @@ -51,10 +51,16 @@ curses.endwin() def update_screen(self): + self.stdscr.clear() + try: + self.do_update_screen() + finally: + self.stdscr.refresh() + + def do_update_screen(self): #c = self.stdscr.getch() #if c==curses.KEY_RESIZE: - self.stdscr.clear() - _, width = self.stdscr.getmaxyx() + height, width = self.stdscr.getmaxyx() #log.info("update_screen() %ix%i", height, width) title = "Xpra top %s" % __version__ try: @@ -68,6 +74,8 @@ sli = self.server_last_info try: self.stdscr.addstr(0, x, title, curses.A_BOLD) + if height<=1: + return server_info = self.dictget("server") build = self.dictget("build") v = build.strget("version") @@ -91,6 +99,8 @@ std(proxy_version or "unknown") ) self.stdscr.addstr(1, 0, server_str) + if height<=2: + return #load and uptime: now = datetime.now() uptime = "" @@ -107,17 +117,28 @@ load_average = ", load average: %1.2f, %1.2f, %1.2f" % float_load self.stdscr.addstr(2, 0, "xpra top - %s%s, %2i users%s" % ( now.strftime("%H:%M:%S"), uptime, nclients, load_average)) + if height<=3: + return thread_info = self.dictget("threads") self.stdscr.addstr(3, 0, "%i threads" % thread_info.intget("count")) + if height<=4: + return #cursor: cursor_info = self.dictget("cursor") cx, cy = cursor_info.intlistget("position", (0, 0)) self.stdscr.addstr(4, 0, "cursor at %ix%i" % (cx, cy)) + if height<=5: + return hpos = 6 for client_no in range(nclients): ci = self.get_client_info(client_no) l = len(ci) + if hpos+2+l>height: + if hpos<height: + more = nclients-client_no + self.stdscr.addstr(hpos, 0, "%i client%s not shown" % (more, engs(more)), curses.A_BOLD) + break self.box(self.stdscr, 1, hpos, width-2, 2+l) for i, info in enumerate(ci): info_text, color = info @@ -125,13 +146,21 @@ self.stdscr.addstr(hpos+i+1, 2, info_text, cpair) hpos += 2+l - hpos += 1 windows = self.dictget("windows") - self.stdscr.addstr(hpos, 0, "%i windows" % len(windows)) - hpos += 1 - for win in windows.values(): + if hpos<height-3: + hpos += 1 + self.stdscr.addstr(hpos, 0, "%i windows" % len(windows)) + hpos += 1 + wins = tuple(windows.values()) + nwindows = len(wins) + for win_no, win in enumerate(wins): wi = self.get_window_info(typedict(win)) l = len(wi) + if hpos+2+l>height: + if hpos<height: + more = nwindows-win_no + self.stdscr.addstr(hpos, 0, "terminal window is too small: %i window%s not shown" % (more, engs(more)), curses.A_BOLD) + break self.box(self.stdscr, 1, hpos, width-2, 2+l) for i, info in enumerate(wi): info_text, color = info @@ -142,9 +171,6 @@ import traceback self.stdscr.addstr(0, 0, str(e)) self.stdscr.addstr(0, 1, traceback.format_exc()) - self.stdscr.refresh() - else: - self.stdscr.refresh() def dictget(self, *parts): d = self.server_last_info diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/client/window_backing_base.py new/xpra-3.0.3/xpra/client/window_backing_base.py --- old/xpra-3.0.2/xpra/client/window_backing_base.py 2019-09-24 15:53:59.000000000 +0200 +++ new/xpra-3.0.3/xpra/client/window_backing_base.py 2019-11-26 16:58:06.000000000 +0100 @@ -52,6 +52,7 @@ PAINT_BOX = envint("XPRA_PAINT_BOX", 0) or envint("XPRA_OPENGL_PAINT_BOX", 0) WEBP_PILLOW = envbool("XPRA_WEBP_PILLOW", False) SCROLL_ENCODING = envbool("XPRA_SCROLL_ENCODING", True) +REPAINT_ALL = envbool("XPRA_REPAINT_ALL", False) #ie: @@ -128,6 +129,7 @@ self.jpeg_decoder = get_codec("dec_jpeg") self.webp_decoder = get_codec("dec_webp") self.draw_needs_refresh = True + self.repaint_all = REPAINT_ALL self.mmap = None self.mmap_enabled = False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/codecs/nv_util.py new/xpra-3.0.3/xpra/codecs/nv_util.py --- old/xpra-3.0.2/xpra/codecs/nv_util.py 2019-09-24 15:53:59.000000000 +0200 +++ new/xpra-3.0.3/xpra/codecs/nv_util.py 2019-11-30 13:36:58.000000000 +0100 @@ -34,15 +34,16 @@ from pynvml import nvmlInit, nvmlShutdown, nvmlSystemGetDriverVersion try: if wrap_nvml_init(nvmlInit): - v = nvmlSystemGetDriverVersion() + try: + v = nvmlSystemGetDriverVersion() + finally: + nvmlShutdown() log("nvmlSystemGetDriverVersion=%s", bytestostr(v)) return v.split(b".") except Exception as e: log("get_nvml_driver_version() pynvml error", exc_info=True) log.warn("Warning: failed to query the NVidia kernel module version using NVML:") log.warn(" %s", e) - finally: - nvmlShutdown() except ImportError as e: log("cannot use nvml to query the kernel module version:") log(" %s", e) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/codecs/nvenc/encoder.pyx new/xpra-3.0.3/xpra/codecs/nvenc/encoder.pyx --- old/xpra-3.0.2/xpra/codecs/nvenc/encoder.pyx 2019-09-24 15:53:59.000000000 +0200 +++ new/xpra-3.0.3/xpra/codecs/nvenc/encoder.pyx 2019-11-18 16:50:49.000000000 +0100 @@ -2236,13 +2236,14 @@ finally: self.cuda_context.pop() except driver.LogicError as e: + log("compress_image%s", (image, quality, speed, options, retry), exc_info=True) if retry>0: raise log.warn("Warning: PyCUDA %s", e) del e self.clean() self.init_cuda() - return self.convert_image(image, options, retry+1) + return self.compress_image(image, options, retry+1) cdef do_compress_image(self, image, options={}): cdef unsigned int stride, w, h diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/gtk_common/gtk_util.py new/xpra-3.0.3/xpra/gtk_common/gtk_util.py --- old/xpra-3.0.2/xpra/gtk_common/gtk_util.py 2019-10-20 14:13:42.000000000 +0200 +++ new/xpra-3.0.3/xpra/gtk_common/gtk_util.py 2019-11-30 13:36:58.000000000 +0100 @@ -7,7 +7,7 @@ import os.path import array -from xpra.util import iround, first_time +from xpra.util import iround, first_time, envint from xpra.os_util import ( strtobytes, bytestostr, WIN32, OSX, PYTHON2, POSIX, @@ -928,6 +928,12 @@ display = display_get_default() if not display: return () + MIN_DPI = envint("XPRA_MIN_DPI", 10) + MAX_DPI = envint("XPRA_MIN_DPI", 500) + def dpi(size_pixels, size_mm): + if size_mm==0: + return 0 + return int(size_pixels * 254 / size_mm / 10) n_screens = display.get_n_screens() get_n_monitors = getattr(display, "get_n_monitors", None) if get_n_monitors: @@ -965,8 +971,27 @@ if workarea: work_x, work_y, work_width, work_height = swork(*workarea) #pylint: disable=not-an-iterable screenlog(" workarea=%s", workarea) + wmm = screen.get_width_mm() + hmm = screen.get_height_mm() + xdpi = dpi(sw, wmm) + ydpi = dpi(sh, hmm) + if xdpi<MIN_DPI or xdpi>MAX_DPI or ydpi<MIN_DPI or ydpi>MAX_DPI: + warn = first_time("invalid-screen-size-%ix%i" % (wmm, hmm)) + if warn: + log.warn("Warning: invalid screen size %ix%imm", wmm, hmm) + if n_monitors>0: + wmm = sum(display.get_monitor(i).get_width_mm() for i in range(n_monitors)) + hmm = sum(display.get_monitor(i).get_height_mm() for i in range(n_monitors)) + xdpi = dpi(sw, wmm) + ydpi = dpi(sh, hmm) + if xdpi<MIN_DPI or xdpi>MAX_DPI or ydpi<MIN_DPI or ydpi>MAX_DPI: + #still invalid, generate one from DPI=96 + wmm = iround(sw*254/10/96.0) + hmm = iround(sh*254/10/96.0) + if warn: + log.warn(" using %ix%i mm", wmm, hmm) item = (screen.make_display_name(), xs(sw), ys(sh), - screen.get_width_mm(), screen.get_height_mm(), + wmm, hmm, monitors, work_x, work_y, work_width, work_height) screenlog(" screen: %s", item) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/gtk_common/gui.py new/xpra-3.0.3/xpra/gtk_common/gui.py --- old/xpra-3.0.2/xpra/gtk_common/gui.py 2019-10-20 14:13:42.000000000 +0200 +++ new/xpra-3.0.3/xpra/gtk_common/gui.py 2019-12-08 12:59:03.000000000 +0100 @@ -242,7 +242,7 @@ icon = get_pixbuf("xpra") if icon: self.set_icon(icon) - self.connect("destroy", self.close) + self.connect("delete-event", self.close) add_close_accel(self, self.close) vbox = gtk.VBox(False, 0) @@ -448,6 +448,7 @@ def close(self, *args): log("close%s", args) self.hide() + return True def run_command(self, *_args): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/platform/darwin/gl_context.py new/xpra-3.0.3/xpra/platform/darwin/gl_context.py --- old/xpra-3.0.2/xpra/platform/darwin/gl_context.py 2019-10-20 14:13:42.000000000 +0200 +++ new/xpra-3.0.3/xpra/platform/darwin/gl_context.py 2019-12-08 12:59:03.000000000 +0100 @@ -48,6 +48,12 @@ assert self.gl_context self.gl_context.flushBuffer() + def update_geometry(self): + glc = self.gl_context + log.warn("update() gl_context=%s", glc) + if glc: + glc.update() + def __del__(self): self.destroy() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/platform/darwin/gui.py new/xpra-3.0.3/xpra/platform/darwin/gui.py --- old/xpra-3.0.2/xpra/platform/darwin/gui.py 2019-09-24 15:54:00.000000000 +0200 +++ new/xpra-3.0.3/xpra/platform/darwin/gui.py 2019-11-18 16:50:50.000000000 +0100 @@ -521,6 +521,13 @@ buf.close() return w, h, "png", image.get_rowstride(), data +def force_focus(duration=2000): + enable_focus_workaround() + from xpra.gtk_common.gobject_compat import import_glib + glib = import_glib() + glib.timeout_add(duration, disable_focus_workaround) + + def show_with_focus_workaround(show_cb): from xpra.gtk_common.gobject_compat import import_glib glib = import_glib() @@ -568,7 +575,8 @@ global __osx_open_signal log("may_show() osx open signal=%s", __osx_open_signal) if not __osx_open_signal: - show_with_focus_workaround(show_cb) + force_focus() + show_cb() glib.timeout_add(delay, may_show) def register_file_handler(handler): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/platform/gui.py new/xpra-3.0.3/xpra/platform/gui.py --- old/xpra-3.0.2/xpra/platform/gui.py 2019-10-22 14:15:47.000000000 +0200 +++ new/xpra-3.0.3/xpra/platform/gui.py 2019-11-18 16:50:50.000000000 +0100 @@ -37,6 +37,11 @@ pass +def force_focus(duration=2000): + #only implemented on macos + pass + + def use_stdin(): stdin = sys.stdin return stdin and stdin.isatty() @@ -277,6 +282,7 @@ platform_import(globals(), "gui", False, "do_ready", "do_init", + "force_focus", "gl_check", "use_stdin", "get_wm_name", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/platform/win32/gl_context.py new/xpra-3.0.3/xpra/platform/win32/gl_context.py --- old/xpra-3.0.2/xpra/platform/win32/gl_context.py 2019-10-30 04:23:47.000000000 +0100 +++ new/xpra-3.0.3/xpra/platform/win32/gl_context.py 2019-12-08 12:59:03.000000000 +0100 @@ -60,6 +60,9 @@ self.paint_hdc = None self.ps = None + def update_geometry(self): + pass + def swap_buffers(self): assert self.paint_hdc log("swap_buffers: calling SwapBuffers(%#x)", self.paint_hdc) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/platform/xposix/gl_context.py new/xpra-3.0.3/xpra/platform/xposix/gl_context.py --- old/xpra-3.0.2/xpra/platform/xposix/gl_context.py 2019-09-24 15:54:00.000000000 +0200 +++ new/xpra-3.0.3/xpra/platform/xposix/gl_context.py 2019-12-08 12:59:03.000000000 +0100 @@ -79,6 +79,9 @@ log("glXMakeCurrent: NULL for xid=%#x", self.xid) GLX.glXMakeCurrent(self.xdisplay, 0, null_context) + def update_geometry(self): + pass + def swap_buffers(self): assert self.valid GLX.glXSwapBuffers(self.xdisplay, self.xid) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/platform/xposix/keyboard.py new/xpra-3.0.3/xpra/platform/xposix/keyboard.py --- old/xpra-3.0.2/xpra/platform/xposix/keyboard.py 2019-10-20 14:13:42.000000000 +0200 +++ new/xpra-3.0.3/xpra/platform/xposix/keyboard.py 2019-12-08 12:59:03.000000000 +0100 @@ -9,7 +9,7 @@ from xpra.keyboard.mask import MODIFIER_MAP from xpra.keyboard.layouts import xkbmap_query_tostring from xpra.log import Logger -from xpra.os_util import is_X11, is_Wayland +from xpra.os_util import is_X11, is_Wayland, bytestostr log = Logger("keyboard", "posix") @@ -85,7 +85,7 @@ if not out: return {} locale = {} - for line in out.splitlines(): + for line in bytestostr(out).splitlines(): parts = line.lstrip(" ").split(": ") if len(parts)==2: locale[parts[0]]=parts[1] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/scripts/config.py new/xpra-3.0.3/xpra/scripts/config.py --- old/xpra-3.0.2/xpra/scripts/config.py 2019-11-05 18:31:07.000000000 +0100 +++ new/xpra-3.0.3/xpra/scripts/config.py 2019-11-08 16:44:54.000000000 +0100 @@ -1007,7 +1007,7 @@ "av-sync" : True, "exit-ssh" : True, "dbus-control" : not WIN32 and not OSX, - "opengl" : "no" if (WIN32 and not PYTHON2) else "probe", + "opengl" : "probe", "mdns" : not WIN32, "swap-keys" : OSX, #only used on osx "desktop-fullscreen": False, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/scripts/main.py new/xpra-3.0.3/xpra/scripts/main.py --- old/xpra-3.0.2/xpra/scripts/main.py 2019-11-05 18:31:07.000000000 +0100 +++ new/xpra-3.0.3/xpra/scripts/main.py 2019-11-26 16:58:06.000000000 +0100 @@ -83,8 +83,12 @@ if "XPRA_ALT_PYTHON_RETRY" in os.environ: del os.environ["XPRA_ALT_PYTHON_RETRY"] - #some environment variables cause us problems if set: - unsetenv("GDK_SCALE") + #turn off gdk scaling to make sure we get the actual window geometry: + os.environ["GDK_SCALE"]="1" + #client side decorations break window geometry, + #disable this "feature" unless explicitly enabled: + if PYTHON3 and os.environ.get("GTK_CSD") is None: + os.environ["GTK_CSD"] = "0" if envbool("XPRA_NOMD5", False): import hashlib @@ -1577,7 +1581,7 @@ app.hello_extra = {"connect" : False} app.start_new_session = sns else: - if PYTHON3 and POSIX and os.environ.get("GDK_BACKEND") is None: + if PYTHON3 and POSIX and os.environ.get("GDK_BACKEND") is None and not OSX: os.environ["GDK_BACKEND"] = "x11" if opts.opengl=="probe": opts.opengl = run_opengl_probe() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/scripts/server.py new/xpra-3.0.3/xpra/scripts/server.py --- old/xpra-3.0.2/xpra/scripts/server.py 2019-10-28 16:04:05.000000000 +0100 +++ new/xpra-3.0.3/xpra/scripts/server.py 2019-11-18 16:50:50.000000000 +0100 @@ -599,7 +599,8 @@ if POSIX: if xrd: os.environ["XDG_RUNTIME_DIR"] = xrd - os.environ["XDG_SESSION_TYPE"] = "x11" + if not OSX: + os.environ["XDG_SESSION_TYPE"] = "x11" if not starting_desktop: os.environ["XDG_CURRENT_DESKTOP"] = opts.wm_name configure_imsettings_env(opts.input_method) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/server/mixins/window_server.py new/xpra-3.0.3/xpra/server/mixins/window_server.py --- old/xpra-3.0.2/xpra/server/mixins/window_server.py 2019-09-24 15:54:01.000000000 +0200 +++ new/xpra-3.0.3/xpra/server/mixins/window_server.py 2019-11-18 16:50:50.000000000 +0100 @@ -303,7 +303,7 @@ ss.refresh(wid, window, opts) def _idle_refresh_all_windows(self, proto): - self.idle_add(self._refresh_windows, proto, self._id_to_window) + self.idle_add(self._refresh_windows, proto, self._id_to_window, {}) def get_window_position(self, _window): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/server/server_core.py new/xpra-3.0.3/xpra/server/server_core.py --- old/xpra-3.0.2/xpra/server/server_core.py 2019-09-30 22:31:59.000000000 +0200 +++ new/xpra-3.0.3/xpra/server/server_core.py 2019-11-26 16:58:06.000000000 +0100 @@ -2039,7 +2039,8 @@ "" : self._html, "dir" : self._www_dir or "", "http-headers-dir" : self._http_headers_dir or "", - } + }, + "mdns" : self.mdns, }) up("network", ni) up("threads", self.get_thread_info(proto)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/server/source/clientdisplay_mixin.py new/xpra-3.0.3/xpra/server/source/clientdisplay_mixin.py --- old/xpra-3.0.2/xpra/server/source/clientdisplay_mixin.py 2019-09-24 15:54:01.000000000 +0200 +++ new/xpra-3.0.3/xpra/server/source/clientdisplay_mixin.py 2019-11-30 13:36:58.000000000 +0100 @@ -5,7 +5,7 @@ # later version. See the file COPYING for details. from xpra.os_util import strtobytes -from xpra.util import get_screen_info +from xpra.util import get_screen_info, envint, first_time, iround from xpra.server.source.stub_source_mixin import StubSourceMixin from xpra.log import Logger @@ -67,8 +67,43 @@ def set_screen_sizes(self, screen_sizes): + log("set_screen_sizes(%s)", screen_sizes) self.screen_sizes = screen_sizes or [] - log("client screen sizes: %s", screen_sizes) + #validate dpi / screen size in mm + #(ticket 2480: GTK3 on macos can return bogus values) + MIN_DPI = envint("XPRA_MIN_DPI", 10) + MAX_DPI = envint("XPRA_MIN_DPI", 500) + def dpi(size_pixels, size_mm): + if size_mm==0: + return 0 + return int(size_pixels * 254 / size_mm / 10) + for i,screen in enumerate(screen_sizes): + if len(screen)<10: + continue + sw, sh, wmm, hmm, monitors = screen[1:6] + xdpi = dpi(sw, wmm) + ydpi = dpi(sh, hmm) + if xdpi<MIN_DPI or xdpi>MAX_DPI or ydpi<MIN_DPI or ydpi>MAX_DPI: + warn = first_time("invalid-screen-size-%ix%i" % (wmm, hmm)) + if warn: + log.warn("Warning: sanitizing invalid screen size %ix%i mm", wmm, hmm) + if monitors: + #[plug_name, xs(geom.x), ys(geom.y), xs(geom.width), ys(geom.height), wmm, hmm] + wmm = sum(monitor[5] for monitor in monitors) + hmm = sum(monitor[6] for monitor in monitors) + xdpi = dpi(sw, wmm) + ydpi = dpi(sh, hmm) + if xdpi<MIN_DPI or xdpi>MAX_DPI or ydpi<MIN_DPI or ydpi>MAX_DPI: + #still invalid, generate one from DPI=96 + wmm = iround(sw*254/10/96.0) + hmm = iround(sh*254/10/96.0) + if warn: + log.warn(" using %ix%i mm", wmm, hmm) + screen = list(screen) + screen[3] = wmm + screen[4] = hmm + screen_sizes[i] = tuple(screen) + log("client validated screen sizes: %s", screen_sizes) def set_desktops(self, desktops, desktop_names): self.desktops = desktops or 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/server/source/windows_mixin.py new/xpra-3.0.3/xpra/server/source/windows_mixin.py --- old/xpra-3.0.2/xpra/server/source/windows_mixin.py 2019-09-24 15:54:01.000000000 +0200 +++ new/xpra-3.0.3/xpra/server/source/windows_mixin.py 2019-12-08 12:59:03.000000000 +0100 @@ -256,7 +256,7 @@ self.last_cursor_sent = cursor_data[:9] w, h, _xhot, _yhot, serial, pixels, name = cursor_data[2:9] #compress pixels if needed: - encoding = None + encoding = "raw" if pixels is not None: #convert bytearray to string: cpixels = strtobytes(pixels) @@ -283,9 +283,7 @@ cursor_data[7] = cpixels cursorlog("do_send_cursor(..) %sx%s %s cursor name='%s', serial=%#x with delay=%s (cursor_encodings=%s)", w, h, (encoding or "empty"), bytestostr(name), serial, delay, self.cursor_encodings) - args = list(cursor_data[:9]) + [cursor_sizes[0]] + list(cursor_sizes[1]) - if self.cursor_encodings and encoding: - args = [encoding] + args + args = [encoding] + list(cursor_data[:9]) + [cursor_sizes[0]] + list(cursor_sizes[1]) self.send_more("cursor", *args) def send_empty_cursor(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/src_info.py new/xpra-3.0.3/xpra/src_info.py --- old/xpra-3.0.2/xpra/src_info.py 2019-11-05 18:31:10.000000000 +0100 +++ new/xpra-3.0.3/xpra/src_info.py 2019-12-10 18:47:53.000000000 +0100 @@ -1,2 +1,2 @@ LOCAL_MODIFICATIONS=0 -REVISION=24387 +REVISION=24692 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/version_util.py new/xpra-3.0.3/xpra/version_util.py --- old/xpra-3.0.2/xpra/version_util.py 2019-09-24 15:54:01.000000000 +0200 +++ new/xpra-3.0.3/xpra/version_util.py 2019-11-08 16:44:54.000000000 +0100 @@ -152,7 +152,11 @@ ld = get_linux_distribution() if ld: info["linux_distribution"] = ld - release = platform_release(pp.release()) + try: + release = platform_release(pp.release()) + except OSError: + log("do_get_platform_info()", exc_info=True) + release = "unknown" info.update({ "" : sys.platform, "name" : platform_name(sys.platform, info.get("linux_distribution") or release), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/x11/gtk_x11/clipboard.py new/xpra-3.0.3/xpra/x11/gtk_x11/clipboard.py --- old/xpra-3.0.2/xpra/x11/gtk_x11/clipboard.py 2019-10-28 16:04:05.000000000 +0100 +++ new/xpra-3.0.3/xpra/x11/gtk_x11/clipboard.py 2019-11-18 16:50:50.000000000 +0100 @@ -48,6 +48,23 @@ sizeof_long = struct.calcsize(b'@L') BLACKLISTED_CLIPBOARD_CLIENTS = os.environ.get("XPRA_BLACKLISTED_CLIPBOARD_CLIENTS", "clipit").split(",") +def parse_translated_targets(v): + trans = {} + #we can't use ";" or "/" as separators + #because those are used in mime-types + #and we use "," and ":" ourselves.. + for entry in v.split("#"): + parts = entry.split(":", 1) + if len(parts)!=2: + log.warn("Warning: invalid clipboard translated target:") + log.warn(" '%s'", entry) + continue + src_target = parts[0] + dst_targets = parts[1].split(",") + trans[src_target] = dst_targets + return trans +TRANSLATED_TARGETS = parse_translated_targets(os.environ.get("XPRA_CLIPBOARD_TRANSLATED_TARGETS", + "text/plain;charset=utf-8:UTF8_STRING,text/plain")) def xatoms_to_strings(data): @@ -385,11 +402,17 @@ if self.targets and target not in self.targets: log.info("client is requesting an unknown target: '%s'", target) - log.info(" valid targets: %s", csv(self.targets)) - if must_discard_extra(target): - log.info(" dropping the request") - nodata() - return + translated_targets = TRANSLATED_TARGETS.get(target, ()) + can_translate = tuple(x for x in translated_targets if x in self.targets) + if can_translate: + target = can_translate[0] + log.info(" using '%s' instead", target) + else: + log.info(" valid targets: %s", csv(self.targets)) + if must_discard_extra(target): + log.info(" dropping the request") + nodata() + return target_data = self.target_data.get(target) if target_data and not self._have_token: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/xpra-3.0.2/xpra/x11/x11_server_base.py new/xpra-3.0.3/xpra/x11/x11_server_base.py --- old/xpra-3.0.2/xpra/x11/x11_server_base.py 2019-10-20 14:13:42.000000000 +0200 +++ new/xpra-3.0.3/xpra/x11/x11_server_base.py 2019-11-30 13:36:58.000000000 +0100 @@ -23,6 +23,7 @@ X11Keyboard = X11KeyboardBindings() SCALED_FONT_ANTIALIAS = envbool("XPRA_SCALED_FONT_ANTIALIAS", False) +SYNC_ICC = envbool("XPRA_SYNC_ICC", True) def _get_antialias_hintstyle(antialias): @@ -189,6 +190,8 @@ def set_icc_profile(self): + if not SYNC_ICC: + return ui_clients = [s for s in self._server_sources.values() if s.ui_client] if len(ui_clients)!=1: screenlog("%i UI clients, resetting ICC profile to default", len(ui_clients))