Skip to content
This repository was archived by the owner on Sep 2, 2021. It is now read-only.

Commit bc515a6

Browse files
authored
Merge pull request #636 from pelatx/linux-window-state
Linux window size and position
2 parents 5775699 + df563cc commit bc515a6

File tree

1 file changed

+191
-19
lines changed

1 file changed

+191
-19
lines changed

appshell/browser/root_window_gtk.cc

Lines changed: 191 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,33 +21,202 @@
2121
#include "appshell/browser/window_test.h"
2222
#include "appshell/common/client_switches.h"
2323

24-
// Brackets specific change.
24+
// Brackets specific changes.
2525
#include "appshell/native_menu_model.h"
2626
#include "appshell/command_callbacks.h"
27+
#include "appshell/appshell_helpers.h"
28+
29+
#define DEFAULT_WINDOW_WIDTH 800
30+
#define DEFAULT_WINDOW_HEIGHT 600
31+
// End of Brackets specific changes.
2732

2833
namespace client {
2934

3035
namespace {
3136

3237
const char kMenuIdKey[] = "menu_id";
3338

34-
bool IsWindowMaximized(GtkWindow* window) {
35-
GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window));
36-
gint state = gdk_window_get_state(gdk_window);
37-
return (state & GDK_WINDOW_STATE_MAXIMIZED) ? true : false;
39+
// Brackets specific changes.
40+
gboolean IsWindowMaximized(GtkWindow* window) {
41+
42+
if (window) {
43+
GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window));
44+
if (gdk_window) {
45+
gint state = gdk_window_get_state(gdk_window);
46+
return (state & GDK_WINDOW_STATE_MAXIMIZED) ? TRUE : FALSE;
47+
}
48+
} else {
49+
return FALSE;
50+
}
51+
3852
}
3953

4054
void MinimizeWindow(GtkWindow* window) {
41-
// Unmaximize the window before minimizing so restore behaves correctly.
42-
if (IsWindowMaximized(window))
43-
gtk_window_unmaximize(window);
4455

45-
gtk_window_iconify(window);
56+
if (window) {
57+
// Unmaximize the window before minimizing so restore behaves correctly.
58+
if (IsWindowMaximized(window))
59+
gtk_window_unmaximize(window);
60+
61+
gtk_window_iconify(window);
62+
}
4663
}
4764

4865
void MaximizeWindow(GtkWindow* window) {
49-
gtk_window_maximize(window);
66+
if (window) {
67+
gtk_window_maximize(window);
68+
}
69+
}
70+
71+
void SaveWindowState(GtkWindow* window) {
72+
73+
if (!window)
74+
return;
75+
76+
gint left = 1;
77+
gint top = 1;
78+
gint width = DEFAULT_WINDOW_WIDTH;
79+
gint height = DEFAULT_WINDOW_HEIGHT;
80+
81+
// Try to center the window.
82+
GdkScreen* screen = gdk_screen_get_default();
83+
if (screen) {
84+
left = (gdk_screen_get_width(screen) - DEFAULT_WINDOW_WIDTH) / 2 ;
85+
top = (gdk_screen_get_height(screen) - DEFAULT_WINDOW_HEIGHT) / 2 ;
86+
}
87+
88+
GKeyFile* key_file = g_key_file_new();
89+
GError* err = NULL;
90+
gchar* filePath = NULL;
91+
92+
if (key_file) {
93+
filePath = g_strdup_printf("%s/%s", appshell::AppGetSupportDirectory().ToString().c_str(), "window.ini");
94+
gboolean maximized = IsWindowMaximized(window);
95+
96+
// If window is not maximized, save current size and position
97+
98+
if (!maximized) {
99+
gtk_window_get_position(window, &left, &top);
100+
gtk_window_get_size(window, &width, &height);
101+
} else if (g_key_file_load_from_file(key_file, filePath, G_KEY_FILE_NONE, &err)) {
102+
103+
// If maximized, load size and position from file
104+
// to preserve last saved values
105+
left = g_key_file_get_integer(key_file, "position", "left", &err);
106+
if (!err)
107+
top = g_key_file_get_integer(key_file, "position", "top", &err);
108+
109+
if (!err)
110+
width = g_key_file_get_integer(key_file, "size", "width", &err);
111+
112+
if (!err)
113+
height = g_key_file_get_integer(key_file, "size", "height", &err);
114+
115+
// If any value can not be read, restore defaults
116+
if (err) {
117+
left = 1;
118+
top = 1;
119+
width = DEFAULT_WINDOW_WIDTH;
120+
height = DEFAULT_WINDOW_HEIGHT;
121+
g_error_free(err);
122+
}
123+
}
124+
125+
// The values would always be written to file.
126+
g_key_file_set_integer(key_file, "position", "left", left);
127+
g_key_file_set_integer(key_file, "position", "top", top);
128+
g_key_file_set_integer(key_file, "size", "width", width - 1); // DelayedResize() 1 pixel compensation
129+
g_key_file_set_integer(key_file, "size", "height", height - 1); // DelayedResize() 1 pixel compensation
130+
g_key_file_set_boolean(key_file, "state", "maximized", maximized);
131+
132+
err = NULL;
133+
g_key_file_save_to_file(key_file, filePath, &err);
134+
135+
if (err) {
136+
fprintf(stderr, "Err -> SaveWindowState(): could not write to `window.ini`. Error Description: %s\n", err->message);
137+
}
138+
} else {
139+
fprintf(stderr, "Err -> SaveWindowState(): could not write to `window.ini`\n");
140+
}
141+
}
142+
143+
void LoadWindowState(GtkWindow* window) {
144+
145+
if (!window) {
146+
return;
147+
}
148+
149+
// Default values for the window state.
150+
gint left = 1;
151+
gint top = 1;
152+
gint width = DEFAULT_WINDOW_WIDTH;
153+
gint height = DEFAULT_WINDOW_HEIGHT;
154+
155+
// Try to center the window.
156+
GdkScreen* screen = gdk_screen_get_default();
157+
if (screen) {
158+
left = (gdk_screen_get_width(screen) - DEFAULT_WINDOW_WIDTH) / 2 ;
159+
top = (gdk_screen_get_height(screen) - DEFAULT_WINDOW_HEIGHT) / 2 ;
160+
}
161+
162+
gboolean maximized = false;
163+
164+
GKeyFile* key_file = g_key_file_new();
165+
bool any_error = false;
166+
GError* err = NULL;
167+
gchar* filePath = g_strdup_printf("%s/%s", appshell::AppGetSupportDirectory().ToString().c_str(), "window.ini");
168+
169+
if (key_file && g_key_file_load_from_file(key_file, filePath, G_KEY_FILE_NONE, &err)) {
170+
171+
left = g_key_file_get_integer(key_file, "position", "left", &err);
172+
if (!err)
173+
top = g_key_file_get_integer(key_file, "position", "top", &err);
174+
175+
if (!err)
176+
width = g_key_file_get_integer(key_file, "size", "width", &err);
177+
178+
if (!err)
179+
height = g_key_file_get_integer(key_file, "size", "height", &err);
180+
181+
if (!err)
182+
maximized = g_key_file_get_boolean(key_file, "state", "maximized", &err);
183+
184+
// If any value can not be readed, set defaults again
185+
if (err) {
186+
left = 1;
187+
top = 1;
188+
width = DEFAULT_WINDOW_WIDTH;
189+
height = DEFAULT_WINDOW_HEIGHT;
190+
maximized = TRUE;
191+
}
192+
} else {
193+
any_error = true;
194+
}
195+
196+
gtk_window_move(GTK_WINDOW(window), left, top);
197+
gtk_window_set_default_size(GTK_WINDOW(window), width, height);
198+
199+
if (maximized)
200+
MaximizeWindow(window);
201+
202+
if (err || any_error) {
203+
204+
// The failure could be because the file may not have been present,
205+
// or the file read itself failed.
206+
// In either of the cases default to maximizing the window.
207+
MaximizeWindow(window);
208+
209+
if (err) {
210+
if (err->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND){
211+
fprintf(stderr, "LoadWindowState(): Could not read %s. Error Description:%s.\n", filePath, err->message);
212+
}
213+
g_error_free(err);
214+
} else {
215+
fprintf(stderr, "LoadWindowState(): Could not read %s.\n", filePath);
216+
}
217+
}
50218
}
219+
// End of Brackets specific changes.
51220

52221
} // namespace
53222

@@ -197,6 +366,7 @@ void RootWindowGtk::Close(bool force) {
197366
REQUIRE_MAIN_THREAD();
198367

199368
if (window_) {
369+
SaveWindowState(GTK_WINDOW(window_));
200370
force_close_ = force;
201371
gtk_widget_destroy(window_);
202372
}
@@ -242,18 +412,20 @@ void RootWindowGtk::CreateRootWindow(const CefBrowserSettings& settings) {
242412
// in the upper-left corner. Maybe there's a better default place to put it?
243413
int x = start_rect_.x;
244414
int y = start_rect_.y;
245-
int width, height;
415+
int width = start_rect_.width;
416+
int height = start_rect_.height;
417+
418+
window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);
419+
420+
// Brackets specific change.
246421
if (start_rect_.IsEmpty()) {
247-
// TODO(port): Also, maybe there's a better way to choose the default size.
248-
width = 800;
249-
height = 600;
422+
LoadWindowState(GTK_WINDOW(window_));
250423
} else {
251-
width = start_rect_.width;
252-
height = start_rect_.height;
424+
gtk_window_move(GTK_WINDOW(window_), x, y);
425+
gtk_window_set_default_size(GTK_WINDOW(window_), width, height);
253426
}
427+
// End of Brackets specific change.
254428

255-
window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);
256-
gtk_window_set_default_size(GTK_WINDOW(window_), width, height);
257429
g_signal_connect(G_OBJECT(window_), "focus-in-event",
258430
G_CALLBACK(&RootWindowGtk::WindowFocusIn), this);
259431
g_signal_connect(G_OBJECT(window_), "window-state-event",
@@ -341,7 +513,7 @@ void RootWindowGtk::CreateRootWindow(const CefBrowserSettings& settings) {
341513
// Most window managers ignore requests for initial window positions (instead
342514
// using a user-defined placement algorithm) and honor requests after the
343515
// window has already been shown.
344-
gtk_window_move(GTK_WINDOW(window_), x, y);
516+
//gtk_window_move(GTK_WINDOW(window_), x, y);
345517

346518
// Windowed browsers are parented to the X11 Window underlying the GtkWindow*
347519
// and must be sized manually. The OSR GTK widget, on the other hand, can be

0 commit comments

Comments
 (0)