diff --git a/gui/choices.py b/gui/choices.py index 4b7df30b0a1d..9621716b6a1a 100644 --- a/gui/choices.py +++ b/gui/choices.py @@ -1098,6 +1098,15 @@ def __iter__(self): ('E1000', _('Intel e82545 (e1000)')), ('VIRTIO', _('VirtIO')), ) +VNC_RESOLUTION = ( + ('1920x1080', _('1920x1080')), + ('1400x1050', _('1400x1050')), + ('1280x1024', _('1280x1024')), + ('1280x960', _('1280x960')), + ('1024x768', _('1024x768')), + ('800x600', _('800x600')), + ('640x480', _('640x480')), +) VM_DISKMODETYPES = ( ('AHCI', _('AHCI')), diff --git a/gui/freeadmin/static/lib/js/freeadmin.js b/gui/freeadmin/static/lib/js/freeadmin.js index d8bb8a708c2c..5bbf36ec9ead 100755 --- a/gui/freeadmin/static/lib/js/freeadmin.js +++ b/gui/freeadmin/static/lib/js/freeadmin.js @@ -1344,6 +1344,7 @@ require([ var nic_mac = registry.byId("id_NIC_mac").domNode.parentNode.parentNode; var vnc_wait = registry.byId("id_VNC_wait").domNode.parentNode.parentNode; var vnc_port = registry.byId("id_VNC_port").domNode.parentNode.parentNode; + var vnc_resolution = registry.byId("id_VNC_resolution").domNode.parentNode.parentNode; domStyle.set(cdrom_path, "display", "none"); domStyle.set(disk_mode, "display", "none"); @@ -1352,6 +1353,7 @@ require([ domStyle.set(nic_mac, "display", "none"); domStyle.set(vnc_wait, "display", "none"); domStyle.set(vnc_port, "display", "none"); + domStyle.set(vnc_resolution, "display", "none"); if(dtype.get('value') == 'DISK') { domStyle.set(disk_mode, "display", ""); @@ -1362,6 +1364,7 @@ require([ domStyle.set(nic_type, "display", ""); domStyle.set(nic_mac, "display", ""); } else if(dtype.get('value') == 'VNC') { + domStyle.set(vnc_resolution, "display", ""); domStyle.set(vnc_port, "display", ""); domStyle.set(vnc_wait, "display", ""); } diff --git a/gui/vm/forms.py b/gui/vm/forms.py index 7e4369101587..fdcabb9579fc 100644 --- a/gui/vm/forms.py +++ b/gui/vm/forms.py @@ -105,6 +105,12 @@ class DeviceForm(ModelForm): validators=[RegexValidator("^([0-9a-fA-F]{2}([::]?|$)){6}$", "Invalid MAC format.")], initial='00:a0:98:FF:FF:FF', ) + VNC_resolution = forms.ChoiceField( + label=_('Resolution'), + choices=choices.VNC_RESOLUTION, + required=False, + initial='1024x768', + ) VNC_port = forms.CharField( label=_('VNC port'), required=False, @@ -151,6 +157,7 @@ def __init__(self, *args, **kwargs): elif self.instance.dtype == 'VNC': self.fields['VNC_wait'].initial = self.instance.attributes.get('wait') self.fields['VNC_port'].initial = self.instance.attributes.get('vnc_port') + self.fields['VNC_resolution'].initial = self.instance.attributes.get('vnc_resolution') def clean(self): vm = self.cleaned_data.get('vm') @@ -185,11 +192,13 @@ def save(self, *args, **kwargs): obj.attributes = { 'wait': self.cleaned_data['VNC_wait'], 'vnc_port': self.cleaned_data['VNC_port'], + 'vnc_resolution': self.cleaned_data['VNC_resolution'], } else: self._errors['dtype'] = self.error_class([_('VNC is only allowed for UEFI')]) self.cleaned_data.pop('VNC_port', None) self.cleaned_data.pop('VNC_wait', None) + self.cleaned_data.pop('VNC_resolution', None) return obj obj.save() diff --git a/src/middlewared/middlewared/plugins/vm.py b/src/middlewared/middlewared/plugins/vm.py index ceb1594d2102..4a511e6aab71 100644 --- a/src/middlewared/middlewared/plugins/vm.py +++ b/src/middlewared/middlewared/plugins/vm.py @@ -116,10 +116,13 @@ def run(self): else: wait = '' + vnc_resolution = device['attributes'].get('vnc_resolution').split('x') + width = vnc_resolution[0] + height = vnc_resolution[1] vnc_port = int(device['attributes'].get('vnc_port', 5900 + self.vm['id'])) args += [ - '-s', '29,fbuf,tcp=0.0.0.0:{},w=1024,h=768,{}'.format(vnc_port, wait), + '-s', '29,fbuf,tcp=0.0.0.0:{},w={},h={},{}'.format(vnc_port, width, height, wait), '-s', '30,xhci,tablet', ]