How to toggle fullscreen borderless on multiple monitors properly - java

I was looking for a way to properly choose the monitor I want to fullscreen on based on the position of the window prior to fullscreening.
I looked online for ages but couldn't find anything so I ended up trying a bunch of things until I got something working.
I figured someone eventually will try to look this problem up and I might as well share my solution.

What I ended up doing is get the virtual screen coordinates of the center of the window using LWJGL2's Display class like so:
int x = Display.getX() + Display.getWidth()/2,
y = Display.getY() + Display.getHeight()/2;
I then used AWT to get all available monitors:
GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()
I iterated through them and got their virtual bounds(and applied any DPI scaling they might have):
Rectangle bounds = screenDevice.getDefaultConfiguration().getDefaultTransform().createTransformedShape(screenDevice.getDefaultConfiguration().getBounds()).getBounds();
EDIT: Slightly altered line so it can support Windows' DPI scaling properly.
If the bounds contained the center of the window, it means that most of the window is probably within that monitor:
if(bounds.contains(x,y))
return bounds; //getMonitorFromWindow()
Then to toggle between windowed borderless fullscreen and normal windowed in LibGDX I did the following:
// config is the LwjglApplicationConfiguration of the application
// upon changing using alt+enter
if(fullscreen) {
config.resizable = false;
Gdx.graphics.setUndecorated(true);
Rectangle monitor = getMonitorFromWindow();
// set to full screen in current monitor
Gdx.graphics.setWindowedMode(monitor.width, monitor.height);
Display.setLocation(monitor.x, monitor.y);
} else {
config.resizable = true;
Gdx.graphics.setUndecorated(false);
Rectangle monitor = getMonitorFromWindow();
// set to windowed centered in current monitor
Gdx.graphics.setWindowedMode((int) (monitor.width * 0.8f), (int) (monitor.height * 0.8f));
Display.setLocation(monitor.x + (int) (monitor.width * 0.1f), monitor.y + (int) (monitor.height * 0.1f));
}
I hope someone would find this useful.

Related

Libgdx controller unresponsive after making application fullscreen

When making the application full screen with the following call:
Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode());
I no longer have signals from my controller. The issue is not solved by changing the display back from full screen like:
Gdx.graphics.setWindowedMode(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2);
I'm using Gdx version: 1.9.8. It appears this was an issue fixed in a previous version, but I'm not sure what the necessary steps are to get the work around functioning.
Here's some posts I found about the issue:
https://github.com/libgdx/libgdx/issues/4723
https://github.com/GoranM/bdx/issues/518
(this one is old) http://www.badlogicgames.com/forum/viewtopic.php?f=11&t=10692
Any help is much appreciated.
*Edit: This is using the controller extension that can be checked from the libgdx set up application. *
Edit2: I can get a responsive controller if I re-poll the controllers like the following:
Array<Controller> controllers = Controllers.getControllers();
However, this cannot be done instantly after changing the display mode; I have to wait some amount of time after. I'm not sure what I need to poll to determine how long I have to wait until the controller instances are valid (also, when it is valid to assign a listener).
Edit3: The only solution I've been able to come up with is to set a flag inside the resize callback like the following
#Override
public void resize(int width, int height) {
resizeDirty = true;
resizeTimestamp = System.currentTimeMillis();
}
Then in my main loop call:
private void controllerCheck() {
if (resizeDirty) {
long currentTime = System.currentTimeMillis();
if (currentTime > resizeTimestamp + controllerResetDelay) {
resizeDirty = false;
//get new controller instance | re-add a controller listener
}
}
}
This isn't ideal, I'd rather find a way to listen to when the change in context is done initializing then update the controllers. But I haven't been able to find a hook for that. I'd appreciate it if anyone knows a better way to go about maintaining controllers with change in display mode.
Why don't you try to use the immersive fullscreen?
If the objective is to set the fullscreen mode, I think this is the better way to.

appium : webview : selenium : How to automate touchend event on a div?

I want to automate a hybrid app using appium.
My app uses touchend events instead of click events for div
How do I automate this touchend events in appium?
For simple click I can find an element and then perform click by simply doing WebElement.click();
How to fire an event for touchend?
I have spend the last few days looking into this same issue. Eventually what I have found is that the Appium touch actions only work on the NATIVE context. However when you are testing/automating a web application you are in WEBVIEW context. So you have to switch to NATIVE, perform the touch actions, then switch back.
Ok, so that doesn't sound to bad. But they can't let it be that simple. So you can not use your Selenium WebElement as an argument in the Touch Actions. You will either have to re-find it using the NATIVE context, or use the elements location and dimensions to calculate a touch position and use that. However, the X and Y coordinates in the NATIVE context are different than those in the WEBVIEW context. So if you need them to be exact, then you have to translate them.
Well, at least that is where I am now. Perhaps someone else can provide some more or better details.
Here is some sample code for a tap which ignores the pixel translation issue. I have only tested this with iOS, but it should work with Android as well.
private void tapElement(AppiumDriver appiumDriver, WebElement element) {
// Locate center of element
Point location = element.getLocation();
Dimension size = element.getSize();
int tapX = location.getX() + (size.getWidth() / 2);
int tapY = location.getY() + (size.getHeight() / 2);
// Execute tap
String originalContext = appiumDriver.getContext();
appiumDriver.context("NATIVE_APP");
TouchAction action = new TouchAction(appiumDriver);
action.tap(tapX, tapY).perform();
appiumDriver.context(originalContext);
}
Have you looked through documentation?
https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/touch-actions.md

Set bar width on ColumnChart from google chart in Java

I am having trouble setting the bar width on my bars in my ColumnChart.
So far I have the following options set:
private Options createOptions() {
Options options = Options.create();
options.setWidth(600);
options.setHeight(400);
options.set3D(true);
options.setEnableTooltip(false);
return options;
}
But it seems like the option for setting the bar width is not there. If I set my width to 600 px, and only have 2 entries/bars, they will each be huge. If I have 10 it will look more normal.
I found the documentation for this here: https://developers.google.com/chart/interactive/docs/gallery/barchart
The variable you'll want to be modifying is bar.groupWidth - you can set it to a size, or a percent ratio. So possibly something like this:
bar: {
groupWidth: 20
}
See some other resources if you need more help:
Google Charts / visualisations column width
Here's another great set of posts:
http://developer.actuate.com/community/forum/index.php?/topic/28797-bar-charts-bar-width/

Determine windows display number and/or layout via java

I have a fullscreen java app that will run on an 8 monitor digital signage type display on a Windows 7 machine. I need to be able to display content on specific physical monitors. Ideally I would like the displays ordered 1-8 in Display Properties -> Settings, however many attempts of unplugging/plugging in and reordering have failed to get the physical monitors to appear in any deterministic order via the Display Properties->Settings. I can reorder them fine, but when my java program retrieves information on the displays it is not in the layout/order that windows has them configured.
GraphicsEnvironment ID returns Strings such as Device0 and Device1, but these do not match the Windows Display numbering as seen in the Display properties. For instance if the layout is 7,4,1,2,3,4,5,6 I still get back Device0, Device1... in which Device0 corresponds to identified screen 1 (not 7 which is the first screen on the left). Is there a way to query the OS to determine what layout the displays are in and/or some other technique to display fullscreen on a specific physical monitor?
You can get the bounds of the screens relative to the big virtual desktop:
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
for (GraphicsDevice gd : ge.getScreenDevices()) {
Rectangle bounds = gd.getDefaultConfiguration().getBounds();
System.out.println(bounds.toString());
}
for my setup this gives:
java.awt.Rectangle[x=0,y=0,width=1280,height=1024]
java.awt.Rectangle[x=1280,y=304,width=1280,height=720]
You can use this information to determine their order. E.g. if you are absolutely sure that your monitors are in a nice grid you can go fullscreen on the upper right monitor like this:
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gdUpperRight = null;
Rectangle bUpperRight = null;
for (GraphicsDevice gd : ge.getScreenDevices()) {
Rectangle b = gd.getDefaultConfiguration().getBounds();
if (bUpperRight == null || b.x > bUpperRight.x || b.y > bUpperRight.y) {
bUpperRight = b;
gdUpperRight = gd;
}
}
gdUpperRight.setFullScreenWindow(myFrame);

using DJ Native Swing API Browser...how to display a specific location in web page & how to turn off the Browser's scroll bar?

ok that's my problem :
i made a JPanel to open web pages but it seams
that it's not working like i want so im looking for a way to make the
DJ NATIVE SWING-SWT API JWebBrowser open a specific location on web site only
and i turn off the scroll bars vertical or horziontal...
so is it possible to do this?
need your help, please answer.
P.S :
i tried these methods to turn off scrolling:
JwebBrowser.setBarsVisible(false);
JwebBrowser.setButtonBarVisible(false);
JwebBrowser.setLocationBarVisible(false);
but i think they have nothing to do with scrolling....
Scroll bars are part of the native component. In fact, if you have frame sets or text components, there can be lots of scroll bars in the same page.
One way of hiding scroll bars is I think to inject Javascript once the target page is loaded that would do this task.
I believe this is what Christopher was getting at. This is similar to the code I used to make sure the rendered native component was at its maximum size. The +20 I found was enough of a fudge to overcome any inconsistencies.
String js_getHeight =
"var D = document;"+
"return Math.max("+
" Math.max(D.body.scrollHeight, D.documentElement.scrollHeight),"+
" Math.max(D.body.offsetHeight, D.documentElement.offsetHeight),"+
" Math.max(D.body.clientHeight, D.documentElement.clientHeight)"+
");";
String js_getWidth =
"var D = document;"+
"return Math.max("+
" Math.max(D.body.scrollWidth, D.documentElement.scrollWidth),"+
" Math.max(D.body.offsetWidth, D.documentElement.offsetWidth),"+
" Math.max(D.body.clientWidth, D.documentElement.clientWidth)"+
");";
webBrowser = new JWebBrowser();
webBrowser.addWebBrowserListener(new WebBrowserAdapter(){
#Override public void loadingProgressChanged(WebBrowserEvent e) {
if(e.getWebBrowser().getLoadingProgress()==100){
NativeComponent nComp = webBrowser.getNativeComponent();
double width = Double.parseDouble(webBrowser.executeJavascriptWithResult(js_getWidth).toString())+20;
double height = Double.parseDouble(webBrowser.executeJavascriptWithResult(js_getHeight).toString())+20;
nComp.setSize(new Dimension((int)width, (int)height));
}
}
});

Categories