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

fix: Used GdkMonitor to set default window size #1743

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
64 changes: 58 additions & 6 deletions packages/app_center/linux/my_application.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <flutter_linux/flutter_linux.h>
#include <handy.h>
#include <gdk/gdk.h>

#include "flutter/generated_plugin_registrant.h"

Expand All @@ -19,6 +20,61 @@ struct _MyApplication {

G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)

// Callback function to set the window size based on the monitor it's located on
void on_window_realize(GtkWidget* widget, gpointer user_data) {
GdkWindow* gdk_window = gtk_widget_get_window(widget);
if (gdk_window == nullptr) {
return;
}

GdkDisplay* display = gdk_window_get_display(gdk_window);
GdkMonitor* monitor = gdk_display_get_monitor_at_window(display, gdk_window);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With my current setup (laptop + external monitor) this always returns the (smaller) laptop screen. @sergio-costas do you know what the problem is here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a little test program, and it happens to me too. I tried using g_signal_connect_after() for "realize" signal, but didn't work. Neither worked using "map" nor "map-event". But if I ask the data "manually" with a button, when the window is fully shown, then it works...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also tested the "draw" event... maybe a solution is to connect to it and, every time the screen resolution changes, update the values...

imagen

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW: also tested "screen-changed" signal, but no dice.


if (monitor == nullptr) {
return;
}

GdkRectangle monitor_geometry;
gdk_monitor_get_geometry(monitor, &monitor_geometry);
gint screen_width = monitor_geometry.width;
gint screen_height = monitor_geometry.height;

// Get the scale factor for high-DPI displays
gint scale_factor = gdk_monitor_get_scale_factor(monitor);

// Predefined sizes
const gint min_width = 800 + 52;
const gint min_height = 600 + 52;
const gint max_width = 1280 + 52;
const gint max_height = 800 + 52;

// Determine default window size based on screen size
gint default_width = screen_width/scale_factor;
gint default_height = screen_height/scale_factor;


// Ensure the window size is within the predefined sizes
if (default_width < min_width) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be default_width < max_width here, so that we show an 800x600 window if the screen is smaller than 1280x800?

default_width = min_width;
} else if (default_width > max_width) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the change from my previous comment, this would need to be >=

default_width = max_width;
}

if (default_height < min_height) {
default_height = min_height;
} else if (default_height > max_height) {
default_height = max_height;
}

GdkGeometry geometry;
geometry.min_width = min_width;
geometry.min_height = min_height;

gtk_window_set_geometry_hints(GTK_WINDOW(widget), nullptr, &geometry, GDK_HINT_MIN_SIZE);
gtk_window_set_default_size(GTK_WINDOW(widget), default_width, default_height);
}


// Implements GApplication::activate.
static void my_application_activate(GApplication* application) {
MyApplication* self = MY_APPLICATION(application);
Expand All @@ -34,14 +90,10 @@ static void my_application_activate(GApplication* application) {
GtkWindow* window = GTK_WINDOW(hdy_application_window_new());
gtk_window_set_application(window, GTK_APPLICATION(application));

GdkGeometry geometry;
// Connect to the "realize" signal to get the monitor size after the window is realized
g_signal_connect(window, "realize", G_CALLBACK(on_window_realize), nullptr);

// TODO: find better solution; set default window size based on available space
geometry.min_width = 800 + 52; // account for shadow from libhandy
geometry.min_height = 600 + 52;
gtk_window_set_geometry_hints(window, nullptr, &geometry, GDK_HINT_MIN_SIZE);

gtk_window_set_default_size(window, 1280 + 52, 800 + 52);
gtk_widget_show(GTK_WIDGET(window));

g_autoptr(FlDartProject) project = fl_dart_project_new();
Expand Down
Loading