Created
April 12, 2013 08:49
-
-
Save vkravets/5370589 to your computer and use it in GitHub Desktop.
Java Full Screen window on Linux OSs using native X11 calling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.linux.X11; | |
import com.sun.jna.Native; | |
import com.sun.jna.NativeLong; | |
import com.sun.jna.platform.unix.X11; | |
import java.awt.*; | |
/** | |
* Author: Vladimir Kravets | |
* E-Mail: [email protected] | |
* Date: 4/10/13 | |
* Time: 12:19 AM | |
* based on code from VLCJ | |
* http://code.google.com/p/vlcj/source/browse/trunk/vlcj/src/main/java/uk/co/caprica/vlcj/runtime/x/LibXUtil.java | |
*/ | |
public class X11FullscreenHelper { | |
private static boolean isFullScreenMode = false; | |
/** | |
* Ask the window manager to make a window full-screen. | |
* <p> | |
* This method sends a low-level event to an X window to request that the | |
* window be made 'real' full-screen - i.e. the window will be sized to fill | |
* the entire screen bounds, and will appear <em>above</em> any window | |
* manager screen furniture such as panels and menus. | |
* <p> | |
* This method should only be called on platforms where X is supported. | |
* <p> | |
* The implementation makes use of the JNA X11 platform binding. | |
* | |
* @param w window to make full-screen | |
* @param fullScreen <code>true</code> to make the window full-screen; <code>false</code> to restore the window to it's original size and position | |
* @return <code>true</code> if the message was successfully sent to the window; <code>false</code> otherwise | |
*/ | |
public static boolean setFullScreenWindow(Window w, boolean fullScreen) { | |
// Use the JNA platform X11 binding | |
X11 x = X11.INSTANCE; | |
X11.Display display = null; | |
try { | |
// Open the display | |
display = x.XOpenDisplay(null); | |
// Send the message | |
int result = sendClientMessage( | |
display, | |
Native.getWindowID(w), | |
"_NET_WM_STATE", | |
new NativeLong[]{ | |
new NativeLong(fullScreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE), | |
x.XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", false), | |
x.XInternAtom(display, "_NET_WM_STATE_ABOVE", false), | |
new NativeLong(0L), | |
new NativeLong(0L) | |
} | |
); | |
isFullScreenMode = (result != 0) && fullScreen; | |
return (result != 0); | |
} | |
finally { | |
if(display != null) { | |
// Close the display | |
x.XCloseDisplay(display); | |
} | |
} | |
} | |
/** | |
* Helper method to send a client message to an X window. | |
* | |
* @param display display | |
* @param wid native window identifier | |
* @param msg type of message to send | |
* @param data0 message data | |
* @param data1 message data | |
* @return <code>1</code> if the message was successfully sent to the window; <code>0</code> otherwise | |
*/ | |
private static int sendClientMessage(X11.Display display, long wid, String msg, NativeLong[] data) { | |
// Use the JNA platform X11 binding | |
assert (data.length == 5); | |
X11 x = X11.INSTANCE; | |
// Create and populate a client-event structure | |
X11.XEvent event = new X11.XEvent(); | |
event.type = X11.ClientMessage; | |
// Select the proper union structure for the event type and populate it | |
event.setType(X11.XClientMessageEvent.class); | |
event.xclient.type = X11.ClientMessage; | |
event.xclient.serial = new NativeLong(0L); | |
event.xclient.send_event = 1; | |
event.xclient.message_type = x.XInternAtom(display, msg, false); | |
event.xclient.window = new X11.Window(wid); | |
event.xclient.format = 32; | |
// Select the proper union structure for the event data and populate it | |
event.xclient.data.setType(NativeLong[].class); | |
System.arraycopy(data, 0, event.xclient.data.l, 0, 5); | |
// Send the event | |
NativeLong mask = new NativeLong(X11.SubstructureRedirectMask | X11.SubstructureNotifyMask); | |
int result = x.XSendEvent(display, x.XDefaultRootWindow(display), 0, mask, event); | |
// Flush, since we're not processing an X event loop | |
x.XFlush(display); | |
// Finally, return the result of sending the event | |
return result; | |
} | |
public static boolean isInFullscreen() { | |
// TODO: to get window attribute and check if _NET_WM_STATE_FULLSCREEN set on window | |
return isFullScreenMode; | |
} | |
// X window message definitions | |
private static final int _NET_WM_STATE_REMOVE = 0; | |
private static final int _NET_WM_STATE_ADD = 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
hey! Thanks for the workaround! I had trouble getting it to work with jruby, so I did a (primitive) ruby port. It's a bit ugly, but it works ;)
https://gist.github.com/flo-l/f383a541d5d93fc7e9b0