Как сделать прозрачную сцену JavaFX прозрачной для событий мыши для Linux X11?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Как сделать прозрачную сцену JavaFX прозрачной для событий мыши для Linux X11?

Сообщение Anonymous »

У меня прозрачная сцена, и мне нужно, чтобы, когда пользователь щелкнул внутри этой сцены, событие мыши было передано окну, которое находится за моей стадией JavaFX (например, если за моей сценой находится текстовый редактор, тогда событие мыши должно быть перешел в это окно редактора). Другими словами, мне нужно, чтобы сцена была прозрачной для событий мыши.
Это мой код:

Код: Выделить всё

public class Test12 extends Application {

@Override
public void start(Stage primaryStage) {
var vBox = new VBox();
vBox.setStyle("-fx-border-width: 1; -fx-border-color: black");
vBox.setMouseTransparent(true);
var scene = new Scene(vBox, 400, 300);
scene.setFill(Color.TRANSPARENT);
scene.getStylesheets().add(this.getClass().getResource("test.css").toExternalForm());
primaryStage.initStyle(StageStyle.TRANSPARENT);
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.setAlwaysOnTop(true);

}

public static void main(String[] args) {
launch(args);
}
}
CSS

Код: Выделить всё

.root { -fx-background-color: transparent; }
Может ли кто-нибудь сказать, как это сделать, если это возможно?
ОБНОВЛЕНИЕ

Это программа на языке C, которая делает правую половину окна прозрачной для событий мыши (используйте программу gcc -o program.c -lX11 -lXext):

Код: Выделить всё

#include 
#include 
#include 
#include 

/* ----------------------------------------------------------------------------------------------- */
#define _NET_WM_STATE_REMOVE        0    // remove/unset property
#define _NET_WM_STATE_ADD           1    // add/set property
#define _NET_WM_STATE_TOGGLE        2    // toggle property

Bool makeAlwaysOnTop(Display* display,  Window mywin) {
int screen = DefaultScreen(display);
Window root = RootWindow(display, screen);
Atom wmStateAbove = XInternAtom( display, "_NET_WM_STATE_ABOVE", 1 );
if( wmStateAbove != None ) {
printf( "_NET_WM_STATE_ABOVE has atom of %ld\n", (long)wmStateAbove );
} else {
printf( "ERROR: cannot find atom for _NET_WM_STATE_ABOVE !\n" );
return False;
}

Atom wmNetWmState = XInternAtom( display, "_NET_WM_STATE", 1 );
if( wmNetWmState != None ) {
printf( "_NET_WM_STATE has atom of %ld\n", (long)wmNetWmState );
} else {
printf( "ERROR: cannot find atom for _NET_WM_STATE !\n"  );
return False;
}

if( wmStateAbove != None )
{
XClientMessageEvent xclient;
memset( &xclient, 0, sizeof (xclient) );
xclient.type = ClientMessage;
xclient.window = mywin;
xclient.message_type = wmNetWmState;
xclient.format = 32;
xclient.data.l[0] = _NET_WM_STATE_ADD;
xclient.data.l[1] = wmStateAbove;
xclient.data.l[2] = 0;
xclient.data.l[3] = 0;
xclient.data.l[4] = 0;
XSendEvent( display,
root,
False,
SubstructureRedirectMask | SubstructureNotifyMask,
(XEvent *)&xclient );
XFlush(display);
return True;
}
return False;
}

/* ----------------------------------------------------------------------------------------------- */

void makeHalfTransparent(Display* dpy,  Window win) {
Pixmap shape = XCreatePixmap(dpy, win, 400, 300, 1);
GC gc = XCreateGC(dpy, shape, 0, NULL);
XSetFillStyle(dpy, gc, FillSolid);
XSetForeground(dpy, gc, 0);
XFillRectangle(dpy, shape, gc, 0, 0, 400, 300);
XSetForeground(dpy, gc, 1);
XFillRectangle(dpy, shape, gc, 0, 0, 200, 300);
XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, shape, ShapeSet);
XFreeGC(dpy, gc);
}

/* ----------------------------------------------------------------------------------------------- */

int main() {
Display *dpy;
Window win;

XEvent event;
int screen;

dpy = XOpenDisplay(NULL);
if (dpy == NULL) {
fprintf(stderr, "Cannot open display\n");
return 1;
}

screen = DefaultScreen(dpy);
win = XCreateSimpleWindow(dpy, RootWindow(dpy, screen), 10, 10, 400, 300, 1, BlackPixel(dpy, screen), WhitePixel(dpy, screen));
XSelectInput(dpy, win, ExposureMask | KeyPressMask);

XMapWindow(dpy, win);
makeAlwaysOnTop(dpy, win);
makeHalfTransparent(dpy, win);

while (1) {
XNextEvent(dpy, &event);
if (event.type == KeyPress) {
break;
}
}

XDestroyWindow(dpy, win);
XCloseDisplay(dpy);
return 0;
}
Это мое приложение JavaFX, которое с помощью JNA должно делать правую половину окна прозрачной для событий мыши (другими словами, я портировал функцию makeHalfTransparent с C на Java):< /p>

Код: Выделить всё

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.unix.X11;
import com.sun.jna.ptr.PointerByReference;
import java.lang.reflect.Method;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.Window;
import javafx.stage.StageStyle;

public class JavaFxTest10 extends Application {

public static interface CustomX11 extends Library {

CustomX11 INSTANCE = (CustomX11) Native.load("X11", CustomX11.class);

X11.Display XOpenDisplay(String display_name);

int XFreeGC(X11.Display display, X11.GC gc);

void XSetForeground(X11.Display display, X11.GC gc, int foreground);

X11.Pixmap XCreatePixmap(X11.Display display, X11.Window w, int width, int height, int depth);

void XFillRectangle(X11.Display display, X11.Pixmap drawable, X11.GC gc, int x, int y, int width, int height);

X11.GC XCreateGC(X11.Display display, X11.Pixmap drawable, int valuemask, X11.XGCValues values);

void XFreePixmap(X11.Display display, X11.Pixmap pixmap);

int XFetchName(X11.Display display, Window w, PointerByReference windowName);

X11.Window XDefaultRootWindow(X11.Display display);

X11.Window XCreateSimpleWindow(X11.Display display, X11.Window rootWindow, int a, int b, int c, int d, int e, int h, int g);

X11.Atom XInternAtom(X11.Display display, String atom_name, boolean only_if_exists);

void XChangeProperty(X11.Display display, X11.Window window, X11.Atom property, X11.Atom type, int format, int mode, Pointer data, int nelements);

void XSetFillStyle(X11.Display display, X11.GC gc, int fillStyle);

void XFillRectangle(X11.Display display,  X11.Drawable drawable, X11.GC gc, int x, int y, int width, int height);
}

public interface Xext extends Library {

Xext INSTANCE = Native.load("Xext", Xext.class);

void XShapeCombineMask(X11.Display display, X11.Window w, int shapeOp, int x, int y, X11.Pixmap shape, int shapeKind);
}

@Override
public void start(Stage primaryStage) {
var button = new Button("Push Me");
button.setOnAction(e -> {
var p = getWIndowPoiter(primaryStage);
var window = getWindow(p);
printWindowTitle(window);//checking pointer
makeHalfTransparent(window, (int) primaryStage.getWidth(), (int) primaryStage.getHeight());
});
var hBox = new HBox(button);
hBox.setStyle("-fx-background-color: green");
var content = new VBox();
content.setMouseTransparent(true);
VBox.setVgrow(content, Priority.ALWAYS);

var mainBox = new VBox(hBox, content);
mainBox.setStyle("-fx-border-width: 1; -fx-border-color: black");
var scene = new Scene(mainBox, 400, 300);
scene.setFill(Color.TRANSPARENT);
scene.getStylesheets().add(this.getClass().getResource("test.css").toExternalForm());
primaryStage.initStyle(StageStyle.TRANSPARENT);
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.setAlwaysOnTop(true);
primaryStage.setTitle("JafaFX Window 777");
}

private Pointer getWIndowPoiter(Stage stage) {
try {
final Method getPeer = Window.class.getDeclaredMethod("getPeer", null);
getPeer.setAccessible(true);
final Object tkStage = getPeer.invoke(stage);
final Method getRawHandle = tkStage.getClass().getMethod("getRawHandle");
getRawHandle.setAccessible(true);
var l = (Long) getRawHandle.invoke(tkStage);
final Pointer pointer = new Pointer(l);
System.out.println(pointer);
return pointer;
} catch (Exception ex) {
System.out.println(ex.getMessage());
ex.printStackTrace();
return null;
}
}

private X11.Window getWindow( Pointer windowPointer) {
X11.Window window = new X11.Window(Pointer.nativeValue(windowPointer));
return window;
}

private void printWindowTitle(X11.Window window) {
final X11 x11 = X11.INSTANCE;
X11.Display display = x11.XOpenDisplay(null);
PointerByReference windowNameReference = new PointerByReference();
int status = X11.INSTANCE.XFetchName(display, window, windowNameReference);

if (status == 1) {
Pointer windowNamePointer = windowNameReference.getValue();
String windowTitle = windowNamePointer.getString(0);
System.out.println("Window Title: "  + windowTitle);
} else {
System.out.println("Failed to fetch window name.");
}
}

public static final int FillSolid = 0;
public static final int ShapeBounding = 0;
public static final int ShapeSet = 0;

private void makeHalfTransparent(X11.Window win, int width, int height) {
X11.Display display = CustomX11.INSTANCE.XOpenDisplay(null);
//Pixmap shape = XCreatePixmap(dpy, win, 400, 300, 1);
X11.Pixmap shape = CustomX11.INSTANCE.XCreatePixmap(display, win, width, height, 1);
//GC gc = XCreateGC(dpy, shape, 0, NULL);
X11.GC gc2 = CustomX11.INSTANCE.XCreateGC(display, shape, 0, null);
//XSetFillStyle(dpy, gc, FillSolid);
CustomX11.INSTANCE.XSetFillStyle(display, gc2, FillSolid);
//XSetForeground(dpy, gc, 0);
CustomX11.INSTANCE.XSetForeground(display, gc2, 0);
//XFillRectangle(dpy, shape, gc, 0, 0, 400, 300);
CustomX11.INSTANCE.XFillRectangle(display, shape, gc2, 0, 0, width, height);
//XSetForeground(dpy, gc, 1);
CustomX11.INSTANCE.XSetForeground(display, gc2, 1);
//XFillRectangle(dpy, shape, gc, 0, 0, 200, 300);
CustomX11.INSTANCE.XFillRectangle(display, shape, gc2, 0, 0, width / 2, height);
//XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, shape, ShapeSet);
Xext.INSTANCE.XShapeCombineMask(display, win, ShapeBounding, 0, 0, shape, ShapeSet);
//XFreeGC(dpy, gc);
CustomX11.INSTANCE.XFreeGC(display, gc2);
}

public static void main(String[] args) {
launch(args);
}
}
Но в JavaFX это не работает. Может ли кто-нибудь помочь мне сделать окно JavaFX прозрачным для событий мыши для Linux X11?

Подробнее здесь: https://stackoverflow.com/questions/791 ... -linux-x11
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»