New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support window decorations on linux #482
Comments
As I'm using NetBeans at work on Windows with menu integrated into title bar, I began to wonder how difficult it would be. As a quick experiment I came up with this:
With that I get this window on Ubuntu Linux: Window interactions work as expected, it does not match the configure GTK Theme, but that is to be expected by client side decorations. I don't understand why The biggest headache will probably be enabling the dynamic switch between OS window decorations and LAF window decorations as the JFrame does not "know" how it was created. @DevCharly what do you think? Patch with changes as described (please expand)diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java
index 4c92ac36..4d6d74a1 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java
@@ -183,14 +183,15 @@ public abstract class FlatLaf
*/
@Override
public boolean getSupportsWindowDecorations() {
- if( SystemInfo.isProjector || SystemInfo.isWebswing || SystemInfo.isWinPE )
- return false;
-
- if( SystemInfo.isWindows_10_orLater &&
- FlatNativeWindowBorder.isSupported() )
- return false;
-
- return SystemInfo.isWindows_10_orLater;
+// if( SystemInfo.isProjector || SystemInfo.isWebswing || SystemInfo.isWinPE )
+// return false;
+//
+// if( SystemInfo.isWindows_10_orLater &&
+// FlatNativeWindowBorder.isSupported() )
+// return false;
+//
+// return SystemInfo.isWindows_10_orLater;
+ return true;
}
@Override
diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java
index 678ed225..adfe174e 100644
--- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java
+++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java
@@ -889,7 +889,7 @@ class DemoFrame
copyMenuItem.addActionListener( new DefaultEditorKit.CopyAction() );
pasteMenuItem.addActionListener( new DefaultEditorKit.PasteAction() );
- if( FlatLaf.supportsNativeWindowDecorations() ) {
+ if( true || FlatLaf.supportsNativeWindowDecorations() ) {
windowDecorationsCheckBoxMenuItem.setSelected( FlatLaf.isUseNativeWindowDecorations() );
menuBarEmbeddedCheckBoxMenuItem.setSelected( UIManager.getBoolean( "TitlePane.menuBarEmbedded" ) );
unifiedTitleBarMenuItem.setSelected( UIManager.getBoolean( "TitlePane.unifiedBackground" ) );
diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/FlatLafDemo.java b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/FlatLafDemo.java
index 8073ede9..116d314b 100644
--- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/FlatLafDemo.java
+++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/FlatLafDemo.java
@@ -22,6 +22,7 @@ import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.extras.FlatInspector;
import com.formdev.flatlaf.extras.FlatUIDefaultsInspector;
import com.formdev.flatlaf.util.SystemInfo;
+import javax.swing.JFrame;
/**
* @author Karl Tauber
@@ -34,6 +35,7 @@ public class FlatLafDemo
static boolean screenshotsMode = Boolean.parseBoolean( System.getProperty( "flatlaf.demo.screenshotsMode" ) );
public static void main( String[] args ) {
+ JFrame.setDefaultLookAndFeelDecorated(true);
// macOS
if( SystemInfo.isMacOS ) {
// enable screen menu bar
|
Thanks, @matthiasblaesing. This looks great and seems to work well with the minor exception (in Gnome 3 on CentOS at least) that dragging to maximize/restore and snap to other windows and the edge of the screen does not seem to work. It would be nice to support the standard system interactions like these (including similar ones with other window managers). Other methods to maximize and snap (double click, max/min/restore buttons, keyboard) do seem to work, so it's still quite usable. |
Tried this on Linux and it works better than expected. I've changed To enable them in your app use e.g.: if( SystemInfo.isLinux ) {
// enable custom window decorations
JFrame.setDefaultLookAndFeelDecorated( true );
JDialog.setDefaultLookAndFeelDecorated( true );
}
That's the downside of enabling custom window decorations.
On Windows 10/11, there was the same problem and the only way to solve it was to implement some C++ code that interacts directly with Windows API, which was complex and time consuming. Similar would be necessary for Linux using X11 API. Also there is OpenJDK Project Wakefield, which will support Wayland display server in the future. So it would be a waste of time to implement something now for X11, and later throw it away and implement same for Wayland... |
@DevCharly, thanks for the quick update. When I entered this issue I was expecting an explanation of why this would be too difficult to implement, but I'm pleasantly surprised. |
Siemens would like to see the drag and snap behavior implemented using the X11 API and would be willing to pay for its development (subject to timing and cost). @DevCharly (or other interested parties), do you have an estimate on when this could be released and what would be a reasonable amount to pay for the development and testing? If there's a better forum for this type of request, I'd be happy to repost this request there. |
If someone want to have a look at this. This is what I tried (feel free to use if it leads to improvements in FlatLaf):
interface X11Ext extends X11 {
X11Ext INSTANCE = Native.load("X11", X11Ext.class);
int XUngrabPointer(Display display, NativeLong time);
}
private static void move_resize(int x, int y) throws HeadlessException {
System.out.printf("%d x %d%n", x, y);
Display display = X11Ext.INSTANCE.XOpenDisplay(null);
Window w = new X11Ext.Window(windowsId);
X11Ext.XEvent event = new X11Ext.XEvent();
event.type = X11Ext.ClientMessage;
event.setType(XClientMessageEvent.class);
event.xclient.type = X11Ext.ClientMessage;
event.xclient.serial = new NativeLong(0);
event.xclient.send_event = 1;
event.xclient.message_type = X11Ext.INSTANCE.XInternAtom(display, "_NET_WM_MOVERESIZE", false);
event.xclient.display = display;
event.xclient.window = w;
event.xclient.format = 32;
event.xclient.data.setType(NativeLong[].class);
event.xclient.data.l[0] = new NativeLong(x);
event.xclient.data.l[1] = new NativeLong(y);
event.xclient.data.l[2] = new NativeLong(10);
event.xclient.data.l[3] = new NativeLong(0);
event.xclient.data.l[4] = new NativeLong(0);
System.out.println(X11Ext.INSTANCE.XUngrabPointer(display, new NativeLong(0)));
System.out.println(X11Ext.INSTANCE.XUngrabKeyboard(display, new NativeLong(0)));
System.out.println(X11Ext.INSTANCE.XSendEvent(display, X11Ext.INSTANCE.XDefaultRootWindow(display), 0, new NativeLong(SubstructureNotifyMask|X11.SubstructureRedirectMask), event));
System.out.println(X11Ext.INSTANCE.XFlush(display));
System.out.println(X11Ext.INSTANCE.XCloseDisplay(display));
System.out.println("Done");
} Theoretically changing the third data element to 8 should make this a mouse move, that did not work for me though. |
@rkeen-siemens thanks for the offer. Is the "drag and snap behavior" the only functionality that you to want?
@matthiasblaesing many thanks for the code. I tried it. BTW is this API available on all Linux distros (that support X11)? Any idea how to show that window popup menu via API? Since the above code uses JNA and depending FlatLaf library on JNA is not an option (like to keep it dependency free), I want to translate the code into C/C++ and build a small |
@DevCharly to my understanding implementors should check the atom list returned by querying the property _NET_SUPPORTED of the root window. I'm not sure if going though direct X11 calls is the preferred way or if it would be better to use gdk. If I remember correctly, both OpenJFX and Swing/AWT are both build on top of gtk and gtk has support for wayland and X11. The drawback is, that you'd have to check if the function is called identically between the supported gtk versions. A runtime lookup of the function symbol might work correctly, if the function call names differ. For the popup - sorry, no idea. As reference this is the GDK function I referenced: https://docs.gtk.org/gdk3/method.Window.begin_move_drag.html |
@DevCharly, thanks for the offer. I'm assuming we will want the other behaviors as well. I'll contact you via email in the next couple days with more details. |
I tested it on Manjaro KDE with X11 and it looks okay: The problems listed by @DevCharly are all present on KDE Plasma, and the additional one is that window shadow disappeared. |
@DevCharly, I sent you an email last week with details on my earlier request for updates. Perhaps you have been busy, but I'm wondering if the message was lost in transit. I'll post my request here as well in case you didn't receive it or others are interested in the work. SummarySiemens would like to see the drag and snap behavior implemented when window decorations are enabled in Linux. Already AvailableThe following are already available and should be maintained:
Scope of WorkThe following should be available as they are currently for native windows (i.e. with window decorations disabled and without the need to hold down a modifier key such as Super before performing the action).
Not Required
AssumptionsThis assumes support is not OS or desktop environment specific (i.e. it should work in GNOME 3 on CentOS and KDE Plasma on Ubuntu). If there are any known issues in the existing implementation or new scope that are platform specific, please provide details of the limitations. Timing and DeliveryWe'd like to have this available in a publicly released version of FlatLaf no later than 30 June 2022. We are happy to test with pre-release versions or build from a branch if needed. Ideally, this would be available in the version bundled in NetBeans 14 at the end of May. If that is not possible, we have our own fork of the NetBeans platform so as long as you can provide instructions for us to update it there that would be acceptable as well. |
These custom window decorations on Linux are awesome! Thank you! But I noticed I'm not getting any window shadows when running on Mint 20.3. Not sure what's different than the other distros where the window shadows work. |
…w menu (right-click on window title bar), if custom window decorations are enabled (issue #482)
…w menu (right-click on window title bar), if custom window decorations are enabled (issue #482)
…y to fix `UnsatisfiedLinkError: ... libjawt.so: cannot open shared object file ...` (issue #482)
Finally, a PR is now available to improve FlatLaf window decorations on Linux: #579 😄 |
The window decorations (including the embedded menu bar and title bar options) would be great to have on linux as well as Windows.
The text was updated successfully, but these errors were encountered: