Skip to content
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

Fill Entire Workspace Fullscreen using GKSQt #184

Open
EmDash00 opened this issue Mar 1, 2024 · 10 comments
Open

Fill Entire Workspace Fullscreen using GKSQt #184

EmDash00 opened this issue Mar 1, 2024 · 10 comments

Comments

@EmDash00
Copy link

EmDash00 commented Mar 1, 2024

Hi, currently using GR as a sort of UI for an experiment; however, I'm not aware of how to set the windowsize for the Qt window that it opens. This is an issue as I don't really know how else I would set some object to be a specific fraction of the screen's width.

I've attached images below.
Screenshot from 2024-03-01 14-47-36

Initial draw size:

Padding after resizing window to fullscreen:

Screenshot from 2024-03-01 14-47-51

What I'd like is for gr.setviewport(0, 1, 0, 1)to fill the entire screen. Do you have any tips?

@jheinen
Copy link
Collaborator

jheinen commented Mar 2, 2024

I don't know, how you produce GR graphics (C/C++, Julia, Python, ...):

In Julia, you could try:

using GR
mw, mh, w, h = inqdspsize()

and then (in landscape mode):

setwswindow(0, 1, 0, mh/mw)
setwsviewport(0, mw, 0, mh)

if you are using low-level GR commands.

With the high-level plots methods, you should use the size argument, e.g.:

plot(randn(10), size=(w, h))

If you are embedding GR graphics in a Qt widget, you cause the above commands in the resize event callback.

@EmDash00
Copy link
Author

EmDash00 commented Mar 13, 2024

Hi thanks for the response. Sorry for the lack of clarification on my language! I'm using Python. I finally got around to trying out your suggestion, and it seems to almost do it; however, I still get some white at the edge of the workspace.

There also appears to be (possibly?) a bug in the behavior of gr.inqwindow() and gr.inqviewport()

#!/usr/bin/env python3

import gr
import gr.pygr

mw, mh, w, h = gr.inqdspsize()

gr.clearws()

print("Window:", gr.inqwindow())
print("Viewport:", gr.inqviewport())

gr.setwswindow(0, 1, 0, mh / mw)
gr.setwsviewport(0, mw, 0, mh)

print("Window:", gr.inqwindow())
print("Viewport:", gr.inqviewport())

x1, y1 = gr.pygr.ndctowc(0, 0)
x2, y2 = gr.pygr.ndctowc(1, mh / mw)

gr.setfillintstyle(gr.INTSTYLE_SOLID)

# Possibly a bug: gr.fillrect(*gr.inqwindow()) doesn't work. See printouts.
gr.fillrect(x1, x2, y1, y2)
gr.updatews()

input()

This prints:

Window: [0.0, 1.0, 0.0, 1.0]
Viewport: [0.2, 0.9, 0.2, 0.9]
Window: [0.0, 1.0, 0.0, 1.0]
Viewport: [0.2, 0.9, 0.2, 0.9]

And yields the following image:

Screenshot from 2024-03-13 16-21-54

It's possible the titlebar of the window is causing this. Do you know of any way of hiding it without using QTGR? There appears to be a setting in Qt that allows this to be possible.

Something like (in PyQt):

from PyQt5.QtCore import Qt

win.setWindowFlags(Qt.Window | Qt.FramelessWindowHint)

@jheinen
Copy link
Collaborator

jheinen commented Mar 14, 2024

You probably mean this:

#!/usr/bin/env python3

import gr
import gr.pygr

mw, mh, w, h = gr.inqdspsize()

gr.setwsviewport(0, mw, 0, mh)
gr.setwswindow(0, 1, 0, mh / mw)

gr.setviewport(0, 1, 0, mh / mw)
gr.setwindow(0, w, 0, h)

print("Viewport: ", gr.inqviewport())
print("Window: ", gr.inqwindow())

gr.setfillintstyle(gr.INTSTYLE_SOLID)
gr.fillrect(*gr.inqwindow())

gr.updatews()

input()

But you are right, the window decoration in Qt seems to cause some trouble. We'll have a look at that ...

@jheinen
Copy link
Collaborator

jheinen commented Mar 14, 2024

The problem should be fixed with this commit.

@EmDash00
Copy link
Author

The problem should be fixed with this commit.

Do you know when I can expect this patch to show up in pygr? I can install the commit to test it when you do.

@EmDash00
Copy link
Author

Okay so I've built it manually on my system. Still getting the same behavior oddly enough (using the code you suggested). Here's my precise printout (I suspect using Wayland won't have a big impact).

import gr
import gr.pygr

import os

print(gr.version())
print(os.environ.get('GRLIB'))

mw, mh, w, h = gr.inqdspsize()

gr.setwsviewport(0, mw, 0, mh)
gr.setwswindow(0, 1, 0, mh / mw)

gr.setviewport(0, 1, 0, mh / mw)
gr.setwindow(0, w, 0, h)

print("Viewport: ", gr.inqviewport())
print("Window: ", gr.inqwindow())

gr.setfillintstyle(gr.INTSTYLE_SOLID)
gr.fillrect(*gr.inqwindow())

gr.updatews()

input()

I've changed the username of the computer to be username for privacy below. I built my gr using the commit you referenced under ~/Apps/git/gr/build

Runtime: 0.73.3.post5 / Python: 1.24.0
/home/username/Apps/git/gr/build/lib/
Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway.
Viewport:  [0.0, 1.0, 0.0, 0.6153846153846154]
Window:  [0.0, 1920.0, 0.0, 1200.0]

As you can see still getting the same behavior with the screen edges. Any help would be appreciated.

Screenshot from 2024-03-14 16-44-40

@IngoMeyer441
Copy link
Member

I can reproduce that our bugfix doesn't work for your code sample. I think in your case, gr.inqdspsize reports the whole screen and not only the useable drawing area. Thus, you only get a black region that has the same aspect ratio as your display.

This example uses the pygr GRWidget to create a custom Qt widget:

#!/usr/bin/env python3

import signal
import sys

import gr
from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt
from qtgr import GRWidget


class FullScreenWidget(GRWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint)

    def draw(self):
        mw, mh, w, h = gr.inqdspsize()

        gr.setwsviewport(0, mw, 0, mh)
        gr.setwswindow(0, 1, 0, mh / mw)
        gr.setviewport(0, 1, 0, h / w)
        gr.setwindow(0, w, 0, h)

        gr.setfillintstyle(gr.INTSTYLE_SOLID)
        gr.fillrect(*gr.inqwindow())


if __name__ == "__main__":
    signal.signal(signal.SIGINT, signal.SIG_DFL)  # Allow the application to be closed with <ctrl-c>
    app = QtWidgets.QApplication(sys.argv)
    widget = FullScreenWidget()
    widget.showFullScreen()
    print("Press <ctrl-c> to exit")
    sys.exit(app.exec())

In that case, inqdspsize returns the actual size of the drawing area. With this code, you can also deactivate the window decorations.

@IngoMeyer441
Copy link
Member

Another tip: You can always use the latest GR development version without compiling by specifying the GR_VERSION environment variable on the python-gr installation:

GR_VERSION=latest python3 -m pip install --force-reinstall --no-cache-dir gr

--no-cache-dir is important, because otherwise the GR C runtime wouldn't be downloaded again.

@EmDash00
Copy link
Author

EmDash00 commented Mar 15, 2024

I can reproduce that our bugfix doesn't work for your code sample. I think in your case, gr.inqdspsize reports the whole screen and not only the useable drawing area. Thus, you only get a black region that has the same aspect ratio as your display.

I tested this and it appears to work.

Unfortunately, I'm already using GR in an application with lots of other threads inside another framework and I think adding a Qt application framework inside would not be worth the extra work it introduces. A workaround I found is to just run the patch to get the size using gr.inqdspsize() and then save those numbers to use in my application.

It's easier for me that way but I feel like gr.inqdspsize() for a for a GKSQt workstation type shouldn't return the monitor size but the total area available after the window decoration is accounted for. Perhaps we can make another function which implements this more desired functionality?

@EmDash00
Copy link
Author

Okay so playing around with it a bit more I found possibly another issue. I'm not sure if it's actually correctly detecting the display size. Here's a quick test.

#!/usr/bin/env python3

import signal
import sys

import gr
import numpy as np
from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt
from qtgr import GRWidget


class FullScreenWidget(GRWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint)

    def draw(self):
        mw, mh, w, h = gr.inqdspsize()

        gr.setwsviewport(0, mw, 0, mh)
        gr.setwswindow(0, 1, 0, mh / mw)
        gr.setviewport(0, 1, 0, h / w)

        gr.setwindow(-1, 1, -1, 1)

        gr.setfillintstyle(gr.INTSTYLE_SOLID)
        gr.fillrect(*gr.inqwindow())

        t = np.linspace(0, 2 * np.pi, num=100)
        gr.setlinecolorind(gr.inqcolorfromrgb(1, 1, 1))
        gr.polyline(np.cos(t), np.sin(t))

        gr.setborderwidth(0)
        gr.setmarkersize(1)
        gr.setmarkertype(gr.MARKERTYPE_SOLID_CIRCLE)
        gr.setmarkercolorind(gr.inqcolorfromrgb(1, 0, 0))

        gr.polymarker([0., -1., -1., 1., 1.], [0., -1., 1., -1., 1.])


if __name__ == "__main__":
    # Allow the application to be closed with <ctrl-c>
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    app = QtWidgets.QApplication(sys.argv)
    widget = FullScreenWidget()
    widget.showFullScreen()
    print("Press <ctrl-c> to exit")
    sys.exit(app.exec())

Screenshot from 2024-03-15 14-18-10

If you look closely the top gets cut off.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants