Scale application differently on different monitors - Ubuntu 16.04
I have found a lot of very solid articles/answers about this topic:
- https://askubuntu.com/a/555812/574648
- https://unix.stackexchange.com/a/213984
- https://askubuntu.com/a/662567/574648
And of course:
- https://wiki.archlinux.org/index.php/Xrandr
- https://wiki.archlinux.org/index.php/HiDPI#Multiple_displays
However, I'm still struggling. My laptop is Dell XPS15. Its display is 3840x2160. I have tried different external monitors, but at the moment the one I use is also Dell with resolution 1920x1080.
When I connect external monitor, some of the panels immediately become very small on 3840x2160 screen. When I try to scale up build-in display, chrome scales, my IDE scales, but displays window along with other windows like NVIDIA X Server settings stay very small. I have tried to play with Scale all window contents to match in Display but to no avail. It's either too big on the external screen or to small on the build-in. I have also tried xrandr with scale param but it gives me:
xrandr --output HDMI-1 --scale 2x2
X Error of failed request: BadValue (integer parameter out of range for operation)
Major opcode of failed request: 140 (RANDR)
Minor opcode of failed request: 26 (RRSetCrtcTransform)
Value in failed request: 0x40
Serial number of failed request: 38
Current serial number in output stream: 39
Ideally, I want several windows of the same application(let's say Chrome or Intellij Idea to be open on different displays and scale independently on them).
EDIT
I am not looking for Scale for menus and title bar, I like the way the bars are. I want windows contents scaled independently. Displays UI forces me to either scale all windows to match Built-id display or the external display. As a result:
-
Scale all window contents to match Build-In Display:
Build-In Display - everything looks perfect; External Display - everything is huge.
-
Scale all window contents to match External Display:
Build-In Display - very small; External Display - everything looks perfect.
I have nvidia driver 340.98
with GT218M [NVS 3100M], Xubuntu 16.04, any results below are from this environment if I don't mention otherwise. Here is my testing environment info, the output of:
sudo apt-get install pastebinit; \
sudo sh -c "lsb_release -sd; \
dmidecode -s system-product-name; echo ==; \
lshw -c display; echo ==; \
xrandr --verbose; echo ==; \
cat /etx/X11/xorg.conf" \
| tee ~/Desktop/ubuntu-graphic-info.txt \
| pastebinit
Weird and complex stack to debug specially using proprietary drivers. Most of the time, I get unexpected behaviors, may be due to lack of knowledge about the current Linux graphics stack setup.
- I wrote this answer before, that may introduce some debugging tools like
xtrace
- Avoid running multiple/sequential
xrandr
commands, only after X server reset. Same command may have different result depending on previous commands. I have noticed that with--scale
(see test case from my answer, linked above)--transform
&--fb
. Still don't know an easy way only by logout/login. So always logout/login before making another trial. - Screenshots take only pixel size image from FB, so I will add camera photos to show the real results.
Method 1: xrandr --output .. --scale HCoefxVCoef
or --scale-from WxH
Note, works fine for me. --scale
is a shortcut for --transform
, see method3
(VGA-0 below DP-3)
xrandr \
--output DP-3 --mode 1280x800 --scale 1x1 --pos 0x0 --fb 2880x2600 \
--output VGA-0 --mode 1440x900 --scale 2x2 --pos 0x800
or:
xrandr \
--output DP-3 --mode 1280x800 --pos 0x0 --fb 2880x2600 \
--output VGA-0 --mode 1440x900 --scale-from 2880x1800 --pos 0x800
FrameBuffer size calculation:
width = max(1280,1440*2) = 2880
height = 800+900*2 = 2600
Results:
-
nvidia xrandr scale screenshot
-
nvidia xrandr scale photo
Method 2: nvidia-settings
View Port In/Out
Note, doesn't work well. nvidia-settings
does not change frame-buffer to the required size as in xrandr
command. It seems a bug (kind of, nvidia
has its own FB), need more research.
Tried to replicate xrandr
setup directly using nvidia-settings
(I used xrandr from method1, marked down nvidia setting, reset settings, then used nvidia-settings directly):
-
gksu nvidia-settings
→ X Server Display Configuration - Select external monitor → advanced...
- Make ViewPortIn & Panning double of ViewPortOut (which is the same as original resolution)
- Leave internal monitor unchanged then Apply
Example:
-
Internal monitor nvidia settings
Position: +0+0 ViewPortIn: 1280x800 ViewPortOut: 1280x800+0+0 Panning: 1280x800
-
External monitor nvidia settings
Position: +1280+0 (rightof) or +0+800 (below) ViewPortIn: 2880x1800 ViewPortOut: 1440x900+0+0 Panning: 2880x1800
Results: Notice the mouse pointer, it can reach all edges of the 2nd monitor even it only draws the top left quarter.
-
nvidia-settings viewportin screenshot
-
nvidia-settings viewportin photo
Update: Well, I could finally get a workaround trick. Add 1px to the width or height of panning (Panning
)
Panning: 2881x1800 or 2880x1801
New Results: I can't explain this, just the background is corrupted if i use below, otherwise every thing seems ok.
-
nvidia-settings viewportin with panning trick screenshot
lowered the color quality of above picture to make less then 2MB imgur limit
-
nvidia -settings viewportin with panning trick photo
Method 3: xrandr --output .. --transform "H,0,0,0,V,0,0,0,1"
Note, works fine for me, same as method1
(VGA-0 right of DP-3)
xrandr \
--output DP-3 -primary --mode 1280x800 --pos 0x0 --transform "1,0,0,0,1,0,0,0,1" --fb 4160x1800 \
--output VGA-0 --mode 1440x900 --transform "2,0,0,0,2,0,0,0,1" --right-of DP-3
FrameBuffer size calculation:
width = 1280+1440*2 = 4160
height = max(800,900*2) = 1800
Results:
-
nvidia xrandr transform screenshot
-
nvidia xrandr transform photo