2

I have a GtkApplication based program that must always be shown maximized. That is easily accomplished by using gtk_window_maximize. The problem is you can still double click or drag the GtkHeaderBar to disable the maximized state.

Is there a way to lock the maximized state or to disable the header behavior? Trying to use gtk_window_set_resizable effectively locks the window size down but it also disallows the maximization effect.

I'm using xfwm4, the default XFCE window manager.

gtk_application_add_window(application, window);
gtk_window_maximize(window);

// Resizing instead of maximizing does not change anything: resetting
// the resizable property shrinks the window to its original size
//gtk_window_set_default_size(window, 1024, 768);
//gtk_window_resize(window, 1024, 768);
//gtk_widget_set_size_request(GTK_WIDGET(window), 1024, 768);

// The following line "demaximizes" the window
//gtk_window_set_resizable(window, FALSE);

// Using a different window type, as suggested by theGtknerd, does
// not help either. The following line makes it behave properly but
// disables the app menu (like any type other than NORMAL).
//gtk_window_set_type_hint(window, GDK_WINDOW_TYPE_HINT_SPLASHSCREEN);

gtk_widget_show_all(GTK_WIDGET(window));

Addendum

I asked on the GTK+ forum and the suggestion I got was to use a fullscreen window for kiosk applications. I tried this approach (I had to rewrite some part of my code because in fullscreen the application headerbar disappears) and it works well.

The original question still stands though.

ntd
  • 7,372
  • 1
  • 27
  • 44

3 Answers3

2

You may wish to check gtk-window-set-decorated. Note that window types are also useful. Due to your window manager and OS enviroment, there is no single best way to achieve what you are looking for, hence my vague response.

Edit:

You could set the size-request of the window to the current size after maximizing the window. This will block the user from making it smaller again.

And here is an MCVE in Python:

#!/usr/bin/env python

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

window = Gtk.Window()

def on_window_destroy(window):
    Gtk.main_quit()
window.connect('destroy', on_window_destroy)

def lock_window_size():
    size = window.get_allocated_size().allocation
    window.set_size_request(size.width, size.height)
GLib.timeout_add_seconds(1, lock_window_size) # allow for the delay of maximizing, etc

window.show_all()
window.maximize()
Gtk.main()
theGtknerd
  • 3,647
  • 1
  • 13
  • 34
  • I don't think the decoration will make any difference, because when maximized the window manager is already stripping it. I'll try to play with the different types and report back, maybe `GDK_WINDOW_TYPE_HINT_DESKTOP` will solve my problem. – ntd Aug 26 '19 at 11:08
  • Unfortunately setting a different window type does not help: I updated the example accordingly. – ntd Aug 26 '19 at 15:32
  • As you can guess, resizing the window is not the same as maximizing it: the window manager decorates the two cases differently. Anyway I just tried and... no joy. I updated the example to reflect this. – ntd Aug 26 '19 at 19:39
  • You could try my MCVE. I don't know if it helps. – theGtknerd Aug 27 '19 at 10:28
  • No need to use 1 second delay: 0 will work just fine. See [my answer here](https://stackoverflow.com/a/14667194/186347) for the rationale. – ntd Aug 27 '19 at 16:01
  • Yes, this will lock the size but not the position. For instance, you can still drag the header bar and move the window around. – ntd Aug 27 '19 at 16:06
0

The issue can be mitigated by disabling some dangerous events, specifically the double click and the drag events on the titlebar. It is an ugly hack though and you can still move the window around by dragging the application menu (or any other widget inside the header bar).

static gboolean
disable_dangerous_events(GtkWidget *widget, GdkEvent *event)
{
    return
        event->type == GDK_MOTION_NOTIFY ||
        event->type == GDK_WINDOW_STATE ?
        GDK_EVENT_STOP : GDK_EVENT_PROPAGATE;
}


...
gtk_application_add_window(application, window);
gtk_window_maximize(window);
g_signal_connect(gs.gtk.window, "event",
                 G_CALLBACK(disable_dangerous_events), NULL);
gtk_widget_show_all(GTK_WIDGET(window));
...

You can still resize the window with shortcut keys but, being run on a touch system, this is not an issue.

ntd
  • 7,372
  • 1
  • 27
  • 44
  • “It is an ugly hack though“ why? How about when window has focus to disable not just double klick but also necessary shortcuts? – Michi Sep 16 '19 at 11:46
  • @Michi I discovered you can still drag the window from the app menu... very bad. At the end this simply does not work, so I rewrote the code leveraging a fullscreen window, as suggested in the [GTK forum](https://discourse.gnome.org/t/how-to-get-a-locked-maximized-window/1670/2?u=ntd). – ntd Oct 16 '19 at 17:01
  • How about if you set windows decorations to FALSE and create your own Menu/nav bar? – Michi Oct 17 '19 at 20:00
  • did you tried it? https://developer.gnome.org/gtk3/stable/GtkWindow.html#GtkWindow--decorated – Michi Oct 17 '19 at 20:20
0

You can set Fullscreen using void gtk_window_fullscreen ():

gtk_window_fullscreen (GTK_WINDOW(gtk_widget_get_root_window (widget)));