linux: improved xrandr-based display mode changing

- fullscreen windows appear on primary screen
- bits per pixel is derived from old getAvailableDisplayModes
- removed debug output
This commit is contained in:
tulius 2014-08-10 01:38:00 +02:00
parent b83d29e265
commit 518ad21d6c
2 changed files with 58 additions and 31 deletions

View File

@ -483,6 +483,15 @@ final class LinuxDisplay implements DisplayImplementation {
window_width = mode.getWidth(); window_width = mode.getWidth();
window_height = mode.getHeight(); window_height = mode.getHeight();
// overwrite arguments x and y - superclass always uses 0,0 for fullscreen windows
// use the coordinates of XRandRs primary screen instead
// this is required to let the fullscreen window appear on the primary screen
if (mode.isFullscreenCapable() && current_displaymode_extension == XRANDR) {
Screen primaryScreen = XRandR.DisplayModetoScreen(Display.getDisplayMode());
x = primaryScreen.xPos;
y = primaryScreen.yPos;
}
current_window = nCreateWindow(getDisplay(), getDefaultScreen(), handle, mode, current_window_mode, x, y, undecorated, parent_window, resizable); current_window = nCreateWindow(getDisplay(), getDefaultScreen(), handle, mode, current_window_mode, x, y, undecorated, parent_window, resizable);
// Set the WM_CLASS hint which is needed by some WM's e.g. Gnome Shell // Set the WM_CLASS hint which is needed by some WM's e.g. Gnome Shell
@ -604,7 +613,7 @@ final class LinuxDisplay implements DisplayImplementation {
private void switchDisplayModeOnTmpDisplay(DisplayMode mode) throws LWJGLException { private void switchDisplayModeOnTmpDisplay(DisplayMode mode) throws LWJGLException {
if (current_displaymode_extension == XRANDR) { if (current_displaymode_extension == XRANDR) {
// let Xrandr set the display mode // let Xrandr set the display mode
XRandR.setConfiguration(XRandR.toScreen(mode)); XRandR.setConfiguration(false, XRandR.DisplayModetoScreen(mode));
} else { } else {
incDisplay(); incDisplay();
try { try {
@ -734,7 +743,7 @@ final class LinuxDisplay implements DisplayImplementation {
saved_mode = AccessController.doPrivileged(new PrivilegedAction<DisplayMode>() { saved_mode = AccessController.doPrivileged(new PrivilegedAction<DisplayMode>() {
public DisplayMode run() { public DisplayMode run() {
XRandR.saveConfiguration(); XRandR.saveConfiguration();
return XRandR.toDisplayMode(XRandR.getConfiguration()); return XRandR.ScreentoDisplayMode(XRandR.getConfiguration());
} }
}); });
break; break;
@ -935,12 +944,17 @@ final class LinuxDisplay implements DisplayImplementation {
try { try {
incDisplay(); incDisplay();
if (current_displaymode_extension == XRANDR) { if (current_displaymode_extension == XRANDR) {
// nGetAvailableDisplayModes cannot be trusted. Use xrandr // nGetAvailableDisplayModes cannot be trusted. Use it only for bitsPerPixel
DisplayMode[] nDisplayModes = nGetAvailableDisplayModes(getDisplay(), getDefaultScreen(), current_displaymode_extension);
int bpp = 24;
if (nDisplayModes.length > 0) {
bpp = nDisplayModes[0].getBitsPerPixel();
}
// get the resolutions and frequencys from XRandR
Screen[] resolutions = XRandR.getResolutions(XRandR.getScreenNames()[0]); Screen[] resolutions = XRandR.getResolutions(XRandR.getScreenNames()[0]);
// quick hack, copy Screens to DisplayModes (todo: get bpp from somewhere, instead of using 24 as default)
DisplayMode[] modes = new DisplayMode[resolutions.length]; DisplayMode[] modes = new DisplayMode[resolutions.length];
for (int i = 0; i < modes.length; i++) { for (int i = 0; i < modes.length; i++) {
modes[i] = new DisplayMode(resolutions[i].width, resolutions[i].height, 24, resolutions[i].freq); modes[i] = new DisplayMode(resolutions[i].width, resolutions[i].height, bpp, resolutions[i].freq);
} }
return modes; return modes;
} else { } else {

View File

@ -156,7 +156,6 @@ public class XRandR
// find and return primary // find and return primary
for (Screen screen : current) { for (Screen screen : current) {
if (screen.name.equals(primaryScreenIdentifier)) { if (screen.name.equals(primaryScreenIdentifier)) {
System.out.println("getConfiguration returned " + screen.width + "x" + screen.height + " @" + screen.freq);
return new Screen[]{screen}; return new Screen[]{screen};
} }
} }
@ -166,12 +165,14 @@ public class XRandR
} }
/** /**
* @param disableOthers
* if screens not included in screens should be turned off (true) or left alone (false)
* @param screens * @param screens
* The desired screen set, may not be <code>null</code> * The desired screen set, may not be <code>null</code>
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if no screens are specified * if no screens are specified
*/ */
public static void setConfiguration(Screen... screens) public static void setConfiguration(boolean disableOthers, Screen... screens)
{ {
if( screens.length == 0 ) if( screens.length == 0 )
throw new IllegalArgumentException( "Must specify at least one screen" ); throw new IllegalArgumentException( "Must specify at least one screen" );
@ -179,6 +180,7 @@ public class XRandR
List<String> cmd = new ArrayList<String>(); List<String> cmd = new ArrayList<String>();
cmd.add( "xrandr" ); cmd.add( "xrandr" );
if (disableOthers) {
// switch off those in the current set not in the new set // switch off those in the current set not in the new set
for ( Screen screen : current ) { for ( Screen screen : current ) {
boolean found = false; boolean found = false;
@ -195,6 +197,7 @@ public class XRandR
cmd.add("--off"); cmd.add("--off");
} }
} }
}
// set up new set // set up new set
for ( Screen screen : screens ) for ( Screen screen : screens )
@ -237,7 +240,7 @@ public class XRandR
*/ */
public static void restoreConfiguration() { public static void restoreConfiguration() {
if (savedConfiguration != null) { if (savedConfiguration != null) {
setConfiguration(savedConfiguration); setConfiguration(true, savedConfiguration);
} }
} }
@ -332,16 +335,26 @@ public class XRandR
screenPosition[1] = Integer.parseInt(m.group(4)); screenPosition[1] = Integer.parseInt(m.group(4));
} }
static Screen toScreen(DisplayMode mode) { static Screen DisplayModetoScreen(DisplayMode mode) {
populate(); populate();
// test: use first screen in list Screen primary = findPrimary(current);
// TODO: replace with "primary" return new Screen(primary.name, mode.getWidth(), mode.getHeight(), mode.getFrequency(), primary.xPos, primary.yPos);
return new Screen(current[0].name, mode.getWidth(), mode.getHeight(), mode.getFrequency(), current[0].xPos, current[0].yPos);
} }
static DisplayMode toDisplayMode(Screen... screens) { static DisplayMode ScreentoDisplayMode(Screen... screens) {
// todo: use "primary" screen populate();
return new DisplayMode(screens[0].width, screens[0].height, 24, screens[0].freq); Screen primary = findPrimary(screens);
return new DisplayMode(primary.width, primary.height, 24, primary.freq);
}
private static Screen findPrimary(Screen... screens) {
for (Screen screen : screens) {
if (screen.name.equals(primaryScreenIdentifier)) {
return screen;
}
}
// fallback
return screens[0];
} }
/** /**