Skip to content

Commit

Permalink
#417: let the user change the bandwidth-limit value at runtime using …
Browse files Browse the repository at this point in the history
…the systray

git-svn-id: https://xpra.org/svn/Xpra/trunk@17259 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Oct 27, 2017
1 parent 14e7ed5 commit 2f60647
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 10 deletions.
Binary file added src/icons/bandwidth_limit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions src/xpra/client/gtk_base/gtk_tray_menu_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

import os
from xpra.gtk_common.gobject_compat import import_gtk, import_glib
gtk = import_gtk()
glib = import_glib()
Expand Down Expand Up @@ -41,6 +42,13 @@
SHOW_SHUTDOWN = envbool("XPRA_SHOW_SHUTDOWN", True)
WINDOWS_MENU = envbool("XPRA_SHOW_WINDOWS_MENU", True)

BANDWIDTH_MENU_OPTIONS = []
for x in os.environ.get("XPRA_BANDWIDTH_MENU_OPTIONS", "1,2,5,10,20,50,100").split(","):
try:
BANDWIDTH_MENU_OPTIONS.append(int(x))
except ValueError:
log.warn("Warning: invalid bandwidth menu option '%s'", x)


LOSSLESS = "Lossless"
QUALITY_OPTIONS_COMMON = {
Expand Down Expand Up @@ -645,6 +653,7 @@ def make_picturemenuitem(self):
menu = gtk.Menu()
picture_menu_item.set_submenu(menu)
self.popup_menu_workaround(menu)
menu.append(self.make_bandwidthlimitmenuitem())
if self.client.windows_enabled and len(self.client.get_encodings())>1:
menu.append(self.make_encodingsmenuitem())
if self.client.can_scale:
Expand All @@ -654,6 +663,41 @@ def make_picturemenuitem(self):
picture_menu_item.show_all()
return picture_menu_item

def make_bandwidthlimitmenuitem(self):
bandwidth_limit_menu_item = self.menuitem("Bandwidth Limit", "bandwidth_limit.png")
menu = gtk.Menu()
self.popup_menu_workaround(menu)
initial_value = self.client.bandwidth_limit or 0
if initial_value>0:
initial_value //= 1000000
def bwitem(bwlimit=0):
if bwlimit>0:
label = "%iMbps" % bwlimit
else:
label = "None"
c = CheckMenuItem(label)
c.set_draw_as_radio(True)
c.set_active(initial_value==bwlimit)
def activate_cb(item, *args):
self.client.bandwidth_limit = bwlimit*1000*1000
self.client.send_bandwidth_limit()
c.connect("toggled", activate_cb)
return c
options = BANDWIDTH_MENU_OPTIONS
if initial_value and initial_value not in options:
options.append(initial_value)
menu.append(bwitem(0))
menu.append(gtk.SeparatorMenuItem())
for v in sorted(options):
menu.append(bwitem(v))
bandwidth_limit_menu_item.set_submenu(menu)
bandwidth_limit_menu_item.show_all()
def set_bwlimitmenu(*_args):
set_sensitive(bandwidth_limit_menu_item, self.client.server_bandwidth_limit_change)
self.client.after_handshake(set_bwlimitmenu)
return bandwidth_limit_menu_item


def make_encodingsmenuitem(self):
encodings = self.menuitem("Encoding", "encoding.png", "Choose picture data encoding", None)
set_sensitive(encodings, False)
Expand Down
5 changes: 5 additions & 0 deletions src/xpra/client/ui_client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1949,6 +1949,7 @@ def parse_server_capabilities(self):
self.server_randr = c.boolget("resize_screen")
log("server has randr: %s", self.server_randr)
self.server_av_sync = c.boolget("av-sync.enabled")
self.server_bandwidth_limit_change = c.boolget("network.bandwidth-limit-change")
avsynclog("av-sync: server=%s, client=%s", self.server_av_sync, self.av_sync)
e = c.strget("encoding")
if e:
Expand Down Expand Up @@ -2265,6 +2266,10 @@ def send_input_devices(self, fmt, input_devices):
self.send("input-devices", fmt, input_devices)


def send_bandwidth_limit(self):
self.send("bandwidth-limit", self.bandwidth_limit)


def start_sending_webcam(self):
with self.webcam_lock:
self.do_start_sending_webcam(self.webcam_option)
Expand Down
38 changes: 28 additions & 10 deletions src/xpra/server/server_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
from xpra.keyboard.mask import DEFAULT_MODIFIER_MEANINGS
from xpra.server.server_core import ServerCore, get_thread_info
from xpra.server.control_command import ArgsControlCommand, ControlError
from xpra.simple_stats import to_std_unit
from xpra.simple_stats import to_std_unit, std_unit
from xpra.child_reaper import getChildReaper
from xpra.os_util import BytesIOClass, thread, livefds, load_binary_file, pollwait, monotonic_time, bytestostr, OSX, WIN32, POSIX, PYTHON3
from xpra.util import typedict, flatten_dict, updict, envbool, envint, log_screen_sizes, engs, repr_ellipsized, csv, iround, \
Expand Down Expand Up @@ -730,6 +730,7 @@ def init_packet_handlers(self):
"webcam-stop": self._process_webcam_stop,
"webcam-frame": self._process_webcam_frame,
"connection-data": self._process_connection_data,
"bandwidth-limit": self._process_bandwidth_limit,
}
self._authenticated_ui_packet_handlers = self._default_packet_handlers.copy()
self._authenticated_ui_packet_handlers.update({
Expand Down Expand Up @@ -1198,15 +1199,7 @@ def drop_client(reason="unknown", *args):
self.disconnect_client(proto, reason, *args)
def get_window_id(wid):
return self._window_to_id.get(wid)
bandwidth_limit = self.bandwidth_limit
if bandwidth_limit is None:
pinfo = proto.get_info()
socket_speed = pinfo.get("socket", {}).get("speed")
if socket_speed:
#auto: use 80% of socket speed if we have it:
bandwidth_limit = socket_speed*AUTO_BANDWIDTH_PCT//100 or 0
else:
bandwidth_limit = 0
bandwidth_limit = self.get_client_bandwidth_limit(proto)
ServerSourceClass = self.get_server_source_class()
ss = ServerSourceClass(proto, drop_client,
self.idle_add, self.timeout_add, self.source_remove,
Expand Down Expand Up @@ -1238,6 +1231,18 @@ def get_window_id(wid):
send_ui = ui_client and not is_request
self.idle_add(self.parse_hello_ui, ss, c, auth_caps, send_ui, share_count)

def get_client_bandwidth_limit(self, proto):
if self.bandwidth_limit is None:
#auto-detect:
pinfo = proto.get_info()
socket_speed = pinfo.get("socket", {}).get("speed")
if socket_speed:
#auto: use 80% of socket speed if we have it:
return socket_speed*AUTO_BANDWIDTH_PCT//100 or 0
else:
return 0
return self.bandwidth_limit


def get_server_source_class(self):
from xpra.server.source import ServerSource
Expand Down Expand Up @@ -1466,6 +1471,9 @@ def get_server_features(self):
f["encoding"] = {
"generic" : True,
}
f["network"] = {
"bandwidth-limit-change" : True,
}
return f

def make_hello(self, source):
Expand Down Expand Up @@ -3308,6 +3316,16 @@ def _process_connection_data(self, proto, packet):
if ss:
ss.update_connection_data(packet[1])

def _process_bandwidth_limit(self, proto, packet):
ss = self._server_sources.get(proto)
if not ss:
return
bandwidth_limit = packet[1]
if self.bandwidth_limit>0:
bandwidth_limit = min(self.bandwidth_limit, bandwidth_limit)
ss.bandwidth_limit = bandwidth_limit
netlog.info("bandwidth-limit changed to %sbps for client %i", std_unit(bandwidth_limit), ss.counter)


def _process_input_devices(self, _proto, packet):
self.input_devices_format = packet[1]
Expand Down

0 comments on commit 2f60647

Please sign in to comment.