Start GLMakie visualization in previous position with previous size

Is there a way to control where will GLMakie position the freshly invoked visualization in my system ?
Currently I am running Debian 11 and whenever I invoke GLMakie the visualization appears behind the current REPL terminal. Then I move it to another monitor in order to see it at the same time as my REPL is open. But the next time I plot something again it’s hidden behind the current terminal.

Is there a way to pop every new GLMakie visualization to a predefined position in my Operating System (optimally last position experienced). The same goes for the window size of GLMakie.

Have you tried the focus_on_show and resolution arguments to GLMakie.Screen?

using GLMakie
GLMakie.Screen(; resolution=(1000, 500), focus_on_show=true)

I’ve been wanting to figure out the other things you mention and I think I’ve got it:

s = GLMakie.Screen()
glw = s.glscreen
cursize = GLMakie.GLFW.GetWindowSize(glw)
GLMakie.GLFW.SetWindowSize(glw, 1000, 100)
# resize the window manually..
GLMakie.GLFW.SetWindowSize(glw, cursize...) # goes back

There’s a GetWindowSize and SetWindowPos that work the same. On MacOS at least, this position seems to be on the extended desktop when there are multiple monitors.

BTW I figured this stuff out by entering GLMakie.GLFW. and then tab-completing to discover what was there. I guess one should probably read the actual docs but they largely point to the GLFW documentation.

Could you also mention how to plot anything on a Screen ?

I 've never really learned how to handle all these internal like Scene, Camera and Screen. To my knowledge, there are also no updated tutorials how to do so.

Maybe a related issue:

I’ve just been doing something like

using GLMakie
scr = GLMakie.Screen(; resolution=(1000, 500))
fig = Figure()
ax = Axis(fig[1,1])
ax2 = Axis(fig[2,1])
display(scr, fig)

There’s a Scene tutorial: Scene tutorial · Makie

I think this stuff is usually controlled by your desktop environment or window manager, and not Makie.

Not sure if there are settings in GNOME. If there aren’t and you are runnig X11 you might be able to use xdotool to hack this together yourself.

that doesn’t work at all on my machine debian 11, julia 1.8.4 and

(othermonitorglmakie) pkg> st
Status `~/code/julia/othermonitorglmakie/Project.toml`
  [f7f18e0c] GLFW v3.4.1
  [e9467ef8] GLMakie v0.8.2
  [ee78f7c6] Makie v0.19.2

Hmm, do you get an error message or just nothing at all?

I get 2 figures and display doesn’t keep the initial resolution.

I think the 2 figures is from the implicit display() that happens at the REPL. Try adding ; to suppress that or run from a script. As for the resolution, my bad – put the that argument on the Figure call, not Screen (or both – if you just display the Screen without a Figure then the window seems to use the resolution in the call to Screen).

So, at the REPL, try this:

using GLMakie
scr = GLMakie.Screen();
fig = Figure(resolution=(200, 500));
ax = Axis(fig[1,1]);
ax2 = Axis(fig[2,1]);
display(scr, fig)

On my system
Windows 11
Julia 1.8.5

function primary_resolution()
    monitor = GLMakie.GLFW.GetPrimaryMonitor() 
    videomode = GLMakie.MonitorProperties(monitor).videomode 
    return (convert(Int64, videomode.width), convert(Int64, videomode.height)) 
end
. . . 

screen = GLMakie.Screen()
gl_screen = screen.glscreen
width, height = primary_resolution()
GLMakie.GLFW.SetWindowSize(gl_screen, width, height)
figure = Figure()
. . .
wait(display(screen, figure))

does not work.

The Figure() function appears to override the GLMakie.GLFW.SetWindowSize() function and the default figure window size is displayed.

figure = Figure(resoluton = primary_resolution())

is required.

I see you’ve addressed this issue above while I was typing.

Will try GLMakie.GLFW.SetWindowPos() to see if it is overridden by Figure() or not.

On the other hand,

function primary_resolution()
    monitor = GLMakie.GLFW.GetPrimaryMonitor() 
    videomode = GLMakie.MonitorProperties(monitor).videomode 
    return (convert(Int64, videomode.width), convert(Int64, videomode.height)) 
end
. . .

    screen = GLMakie.Screen()
    gl_screen = screen.glscreen
    GLMakie.GLFW.SetWindowPos(gl_screen, 0, 30)

    figure = Figure(resolution = primary_resolution())
    . . .
    wait(display(screen, figure))

does work. One can use this code fragment to set the position of the screen + display on the monitor.

primary_resolution() returns the maximum resolution of the monitor. some times that’s fine but not always. This looks like it should be covered by fullscreen = false on Screen attributes but it is also not working for me.

Thanks for your help. My workflow ended up being something like this.
First define following function:

function restartfig(s::GLMakie.Screen ;pos = (5400, 50), res = (1000, 500))
    GLMakie.GLFW.SetWindowPos(s.glscreen, pos...)
    fig = Figure(resolution = res)
    display(s, fig)
    return fig
end

Then on your REPL:

julia> screen = GLMakie.Screen(); # initiate just once a Screen

julia> fig = restartfig(screen); # get figure to plot on

julia> scatter(fig[1,1], [0,1,2,4], [0,1,2,4]) # do your thing
Makie.AxisPlot(Axis (1 plots), Scatter{Tuple{Vector{Point{2, Float32}}}})

julia> fig = restartfig(screen); # restart fig on screen and get new figure to plot on

julia> scatter(fig[1,1], [0,1,2,4,5,6,7], [0,1,2,4,5,6,7]) # do your thing Vol2 and keep on like that
Makie.AxisPlot(Axis (1 plots), Scatter{Tuple{Vector{Point{2, Float32}}}})

Thanks for your code examples.
My next question was to be how to call Figure() repeatedly after a single call to Screen(), but you’ve addressed it with the code in your post. I adapted it for scripts run using VS Code.

In future version of GLMakie, it would be ideal if one could specify both the resolution - size to be displayed and the position on the monitor of the display in Figure().

1 Like