Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ce75a58
Improve function naming
jeremypw Jun 30, 2025
e34c919
Allow Application to handle window quit request
jeremypw Jun 30, 2025
f730267
Merge branch 'master' into jeremypw/save_all_window_docs
jeremypw Jul 16, 2025
dffedfa
Merge branch 'master' into jeremypw/save_all_window_docs
jeremypw Aug 9, 2025
d2f4067
Merge branch 'master' into jeremypw/save_all_window_docs
jeremypw Aug 13, 2025
b167f53
Do not move docs to another window
jeremypw Aug 13, 2025
8a117e7
Handle new docs differently if not closing last window
jeremypw Aug 13, 2025
2d41ce5
Separate action to close app and close window
jeremypw Aug 13, 2025
a70893b
Merge branch 'master' into jeremypw/save_all_window_docs
zeebok Oct 17, 2025
00cb116
Merge branch 'master' into jeremypw/save_all_window_docs
jeremypw Oct 18, 2025
15fe37b
Merge branch 'master' into jeremypw/save_all_window_docs
jeremypw Nov 4, 2025
27300ee
Merge branch 'master' into jeremypw/save_all_window_docs
zeebok Jan 1, 2026
3d806bb
DRY
jeremypw Jan 3, 2026
65fb8a8
Merge branch 'master' into jeremypw/save_all_window_docs
jeremypw Jan 25, 2026
12e2e30
Merge branch 'master' into jeremypw/save_all_window_docs
jeremypw Feb 16, 2026
67fef22
Merge branch 'master' into jeremypw/save_all_window_docs
zeebok Mar 31, 2026
53933a7
Merge branch 'master' into jeremypw/save_all_window_docs
zeebok Apr 18, 2026
38af3a5
Merge branch 'master' into jeremypw/save_all_window_docs
zeebok Apr 20, 2026
97d905a
Merge branch 'master' into jeremypw/save_all_window_docs
zeebok Apr 20, 2026
edcf5c8
Merge branch 'master' into jeremypw/save_all_window_docs
jeremypw Apr 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions src/Application.vala
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,38 @@ namespace Scratch {
return windows.length () > 0 ? windows.last ().data as MainWindow : null;
}

public async void handle_quit_app () {
unowned List<Gtk.Window> windows;
windows = get_windows ();
//NOTE This yields the last opened window at head of list (may change in future?)
while (windows.length () > 0) {
if (!yield handle_quit_window ((MainWindow) (windows.first ().data))) {
return;
}

windows = get_windows ();
}
Comment thread
jeremypw marked this conversation as resolved.

return;
}

public async bool handle_quit_window (MainWindow window_to_close) {
unowned List<Gtk.Window> windows = get_windows ();
var is_last_window = windows.length () == 1;
if (!yield window_to_close.check_unsaved_changes (is_last_window)) {
return false;
}

if (is_last_window) {
window_to_close.before_quit (); // Update settings
}
// Just destroy window - we have already checked whether any docs need saving
// When the last window is removed and destroyed the app quits.
remove_window (window_to_close);
window_to_close.destroy ();
return true;
}

public static int main (string[] args) {
// By default, profile whole app when profiling is enabled in meson_options.txt
// These conditional statements can be moved to profile sections of code
Expand Down
36 changes: 19 additions & 17 deletions src/MainWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ namespace Scratch {
public const string ACTION_TO_UPPER_CASE = "action-to-upper-case";
public const string ACTION_DUPLICATE = "action-duplicate";
public const string ACTION_FULLSCREEN = "action-fullscreen";
public const string ACTION_QUIT = "action-quit";
public const string ACTION_QUIT = "action-quit-app";
public const string ACTION_CLOSE_WINDOW = "action-close-window";
public const string ACTION_ZOOM_DEFAULT = "action-zoom-default";
public const string ACTION_ZOOM_IN = "action-zoom-in";
public const string ACTION_ZOOM_OUT = "action-zoom-out";
Expand Down Expand Up @@ -160,7 +161,8 @@ namespace Scratch {
{ ACTION_TO_UPPER_CASE, action_to_upper_case },
{ ACTION_DUPLICATE, action_duplicate },
{ ACTION_FULLSCREEN, action_fullscreen },
{ ACTION_QUIT, action_quit },
{ ACTION_QUIT, action_quit_app },
{ ACTION_CLOSE_WINDOW, action_close_window },
{ ACTION_ZOOM_DEFAULT, action_set_default_zoom },
{ ACTION_ZOOM_IN, action_zoom_in },
{ ACTION_ZOOM_OUT, action_zoom_out},
Expand Down Expand Up @@ -225,6 +227,7 @@ namespace Scratch {
action_accelerators.set (ACTION_DUPLICATE, "<Control>d");
action_accelerators.set (ACTION_FULLSCREEN, "F11");
action_accelerators.set (ACTION_QUIT, "<Control>q");
action_accelerators.set (ACTION_CLOSE_WINDOW, "<Control>F4");
action_accelerators.set (ACTION_ZOOM_DEFAULT, "<Control>0");
action_accelerators.set (ACTION_ZOOM_DEFAULT, "<Control>KP_0");
action_accelerators.set (ACTION_ZOOM_IN, "<Control>plus");
Expand Down Expand Up @@ -716,7 +719,7 @@ namespace Scratch {
}

protected override bool delete_event (Gdk.EventAny event) {
action_quit ();
action_close_window ();
return true;
}

Expand Down Expand Up @@ -804,10 +807,10 @@ namespace Scratch {
}

// Check that there no unsaved changes and all saves are successful
private async bool check_unsaved_changes () {
public async bool check_unsaved_changes (bool app_closing) {
document_view.is_closing = true;
foreach (var doc in document_view.docs) {
if (!yield (doc.do_close (true))) {
if (!yield (doc.do_close (app_closing))) {
document_view.current_document = doc;
return false;
}
Expand Down Expand Up @@ -841,7 +844,7 @@ namespace Scratch {
}
}

private void update_saved_state () {
private void update_window_state_setting () {
// Save window state
var state = get_window ().get_state ();
if (Gdk.WindowState.MAXIMIZED in state) {
Expand All @@ -865,14 +868,14 @@ namespace Scratch {

// SIGTERM/SIGINT Handling
public bool quit_source_func () {
action_quit ();
action_quit_app ();
return false;
}

// For exit cleanup
private void handle_quit () {
document_view.save_opened_files ();
update_saved_state ();
public void before_quit () {
document_view.update_opened_files_setting ();
update_window_state_setting ();
}

public void set_default_zoom () {
Expand Down Expand Up @@ -959,13 +962,12 @@ namespace Scratch {
preferences_dialog.present ();
}

private void action_quit () {
handle_quit ();
check_unsaved_changes.begin ((obj, res) => {
if (check_unsaved_changes.end (res)) {
app.quit ();
}
});
private void action_close_window () {
app.handle_quit_window.begin (this);
}

private void action_quit_app () {
app.handle_quit_app.begin ();
}

private void action_open () {
Expand Down
10 changes: 5 additions & 5 deletions src/Widgets/DocumentView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public class Scratch.Widgets.DocumentView : Gtk.Box {
var should_close = doc.do_close.end (res);
// Ensure removed doc is saved by handling this first
if (!is_closing) {
save_opened_files ();
update_opened_files_setting ();
}
//`page-detached` handler will perform rest of necessary cleanup
tab_view.close_page_finish (tab, should_close);
Expand Down Expand Up @@ -337,7 +337,7 @@ public class Scratch.Widgets.DocumentView : Gtk.Box {
if (range != SelectionRange.EMPTY) {
Idle.add_full (GLib.Priority.LOW, () => { // This helps ensures new tab is drawn before opening document.
current_document.source_view.select_range (range);
save_opened_files ();
update_opened_files_setting ();

return false;
});
Expand All @@ -364,7 +364,7 @@ public class Scratch.Widgets.DocumentView : Gtk.Box {
doc.source_view.cursor_position = cursor_position;
}

save_opened_files ();
update_opened_files_setting ();
}

public void next_document () {
Expand Down Expand Up @@ -399,7 +399,7 @@ public class Scratch.Widgets.DocumentView : Gtk.Box {
}
}

public void save_opened_files () {
public void update_opened_files_setting () {
if (privacy_settings.get_boolean ("remember-recent-files")) {
var vb = new VariantBuilder (new VariantType ("a(si)"));
docs.foreach ((doc) => {
Expand Down Expand Up @@ -542,7 +542,7 @@ public class Scratch.Widgets.DocumentView : Gtk.Box {
current_document = doc;
}

save_opened_files ();
update_opened_files_setting ();
}

private unowned Hdy.TabView? on_doc_to_new_window (Hdy.TabView tab_view) {
Expand Down