select certain monitor for going fullscreen with gtk

Question:

I intend to change the monitor where I show a fullscreen window.
This is especially interesting when having a projector hooked up.

I’ve tried to use fullscreen_on_monitor but that doesn’t produce any visible changes.

Here is a non-working example:

#!/usr/bin/env python
import sys

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk

w = Gtk.Window()

screen = Gdk.Screen.get_default()
print ("Montors: %d" % screen.get_n_monitors())
if len(sys.argv) > 1:
    n = int(sys.argv[1])
else:
    n = 0

l = Gtk.Button(label="Hello, %d monitors!" % screen.get_n_monitors())
w.add(l)
w.show_all()

w.fullscreen_on_monitor(screen, n)
l.connect("clicked", Gtk.main_quit)
w.connect("destroy", Gtk.main_quit)
Gtk.main()

I get to see the window on the very same monitor (out of 3), regardless of the value I provide.

My question is: how do I make the fullscreen window appear on a different monitor?

Asked By: Frederick Nord

||

Answers:

The problem seems to be that Gtk just ignores the monitor number, it will always fullscreen the window on the monitor on which the window currently is positioned. This sucks, but we can use that to make it work the way we want to.

But first some theory about multiple monitors, they aren’t actually separate monitors for your pc. It considers them to collectively form one screen which share the same global origin. On that global screen each monitor has a origin relative to the global origin, just like windows.

Because we know that Gtk will always fullscreen on the monitor on which the window is we can simply move the window to the origin of the monitor using window.move(x,y) and then call window.fullscreen().

(The move function will move the window to a position (x,y) relative to it’s parent, which in the case of the main window is the global screen.)

Combining all this we get this, which works perfectly on Windows 10:

def fullscreen_at_monitor(window, n):
    screen = Gdk.Screen.get_default()

    monitor_n_geo = screen.get_monitor_geometry(n)
    x = monitor_n_geo.x
    y = monitor_n_geo.y

    window.move(x,y)

    window.fullscreen()
Answered By: B8vrede

Here is an updated version of @B8vrede’s answer, because get_monitor_geometry is deprecated since 3.22.

def fullscreen_at_monitor(window, n):
    display = Gdk.Display.get_default()
    monitor = Gdk.Display.get_monitor(display, n)
    geometry = monitor.get_geometry()
    x = geometry.x
    y = geometry.y
    window.move(x, y)
    window.fullscreen()
Answered By: Nicolai Weitkemper
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.