Fix monitor selection: resolve /f and /monitors: parameter conflict

Root cause: /f (fullscreen) parameter conflicts with /monitors: in FreeRDP 2.11.5
causing specific monitor selection to fall back to single monitor display.

Changes:
- Reorder command generation to check monitor config before resolution
- Skip /f when using specific monitor selection (/monitors:1,2 or /monitors:1,2,0)
- Keep /f only for 'All Monitors' and single monitor scenarios
- Add test script to validate new command generation logic

This should fix the issue where:
- 'All Monitors' works correctly (uses /f + /multimon)
- '2 Monitors' and '3 Monitors' were showing only 1 monitor

Expected result: /monitors:1,2 without /f should now properly display on 2 monitors
This commit is contained in:
root
2025-09-18 11:01:39 +02:00
parent 87598da623
commit e727430a4f
2 changed files with 97 additions and 5 deletions

View File

@@ -842,10 +842,17 @@ Multi-Monitor Support:
if conn.get("domain"): if conn.get("domain"):
cmd.append(f"/d:{conn['domain']}") cmd.append(f"/d:{conn['domain']}")
# Resolution # Check monitor configuration first to determine resolution handling
multimon = conn.get("multimon", "No")
use_specific_monitors = multimon in ["2 Monitors", "3 Monitors", "4 Monitors"]
# Resolution - avoid /f with specific monitor selection due to conflicts
resolution = conn.get("resolution", "1920x1080") resolution = conn.get("resolution", "1920x1080")
if resolution == "Full Screen": if resolution == "Full Screen" and not use_specific_monitors:
cmd.append("/f") cmd.append("/f")
elif resolution == "Full Screen" and use_specific_monitors:
# Don't use /f with specific monitors - let /monitors: determine the layout
self.logger.info("Skipping /f (fullscreen) due to specific monitor selection")
else: else:
cmd.append(f"/size:{resolution}") cmd.append(f"/size:{resolution}")
@@ -853,11 +860,9 @@ Multi-Monitor Support:
color_depth = conn.get("color_depth", 32) color_depth = conn.get("color_depth", 32)
cmd.append(f"/bpp:{color_depth}") cmd.append(f"/bpp:{color_depth}")
# Multiple monitors # Multiple monitors - use /monitors: without /multimon for specific selection
multimon = conn.get("multimon", "No")
if multimon == "2 Monitors": if multimon == "2 Monitors":
monitor_list = self._get_best_monitor_selection(2) monitor_list = self._get_best_monitor_selection(2)
# Try using /monitors without /multimon for specific monitor selection
cmd.append(f"/monitors:{monitor_list}") cmd.append(f"/monitors:{monitor_list}")
self.logger.info(f"Using specific monitors for 2 monitors: {monitor_list}") self.logger.info(f"Using specific monitors for 2 monitors: {monitor_list}")
elif multimon == "3 Monitors": elif multimon == "3 Monitors":

View File

@@ -0,0 +1,87 @@
#!/usr/bin/env python3
import subprocess
def get_best_monitor_selection(count):
"""Get the best monitor selection based on layout"""
try:
result = subprocess.run(['xfreerdp', '/monitor-list'],
capture_output=True, text=True, timeout=5)
if result.returncode == 0:
lines = result.stdout.strip().split('\n')
monitors = []
for line in lines:
cleaned_line = line.strip()
is_primary = cleaned_line.startswith('*')
cleaned_line = cleaned_line.replace('*', '').strip()
if '[' in cleaned_line and ']' in cleaned_line and 'x' in cleaned_line and '+' in cleaned_line:
parts = cleaned_line.split()
if len(parts) >= 3:
id_part = parts[0]
pos_part = parts[2]
if '[' in id_part and ']' in id_part:
monitor_id = int(id_part.strip('[]'))
x_pos = int(pos_part.split('+')[1])
monitor_info = (monitor_id, x_pos, is_primary)
monitors.append(monitor_info)
monitors.sort(key=lambda x: x[1])
selected = [str(m[0]) for m in monitors[:count]]
return ','.join(selected)
except:
pass
return ','.join([str(i) for i in range(count)])
def test_new_command_logic():
print("=== Testing Fixed Monitor Selection Logic ===")
print()
test_cases = [
("2 Monitors", "Full Screen"),
("3 Monitors", "Full Screen"),
("All Monitors", "Full Screen"),
("2 Monitors", "1920x1080"),
]
for multimon, resolution in test_cases:
print(f"Testing: {multimon} with {resolution}")
cmd = ["xfreerdp", "/v:test-server", "/u:testuser", "/p:password"]
# Check monitor configuration first
use_specific_monitors = multimon in ["2 Monitors", "3 Monitors", "4 Monitors"]
# Resolution handling
if resolution == "Full Screen" and not use_specific_monitors:
cmd.append("/f")
print(" → Using /f (fullscreen)")
elif resolution == "Full Screen" and use_specific_monitors:
print(" → Skipping /f due to specific monitor selection")
else:
cmd.append(f"/size:{resolution}")
print(f" → Using /size:{resolution}")
cmd.append("/bpp:32")
# Monitor handling
if multimon == "2 Monitors":
monitor_list = get_best_monitor_selection(2)
cmd.append(f"/monitors:{monitor_list}")
print(f" → Using /monitors:{monitor_list}")
elif multimon == "3 Monitors":
monitor_list = get_best_monitor_selection(3)
cmd.append(f"/monitors:{monitor_list}")
print(f" → Using /monitors:{monitor_list}")
elif multimon == "All Monitors":
cmd.append("/multimon")
print(f" → Using /multimon")
cmd_str = ' '.join(cmd).replace("/p:password", "/p:***")
print(f" Command: {cmd_str}")
print()
if __name__ == "__main__":
test_new_command_logic()