Skip to content

Commit 601cd32

Browse files
committed
Implement graceful shutdown
1 parent e725a8c commit 601cd32

File tree

13 files changed

+116
-73
lines changed

13 files changed

+116
-73
lines changed

call.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,13 @@ static void commandVersion() {
1111
// exit
1212

1313
static void commandExit(pipe_buffer *target) {
14+
static int exitCount = 0;
15+
if (exitCount++ == 0) {
16+
top_signal_disconnect();
17+
}
1418
io_stop(target);
1519
if (io_exited()) {
20+
gtk_widget_destroy(top);
1621
g_application_quit(G_APPLICATION(app));
1722
}
1823
}
@@ -225,7 +230,6 @@ _Static_assert(sizeof size == 8, "wrong size align");
225230
static void setSize() {
226231
gtk_window_move(GTK_WINDOW(top), size.x, size.y);
227232
gtk_window_resize(GTK_WINDOW(top), size.width, size.height);
228-
// gtk_widget_show(top);
229233
}
230234

231235
static void commandSize(pipe_buffer *target) { parameters_to_call(target, &size, sizeof size, setSize); }

event.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include "glib-object.h"
12
#include "terminal.h"
23
#include <gtk/gtk.h>
34
#include <math.h>
@@ -46,7 +47,7 @@ static void write_configure_event_once(configure_event *e) {
4647
pipe_event_flush();
4748
}
4849

49-
static void on_size_allocate(GtkWidget *widget, GtkAllocation *allocation, void *data) {
50+
static void on_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer data) {
5051
layoutOffsetX = allocation->x;
5152
layoutOffsetY = allocation->y;
5253
gint width, height;
@@ -201,7 +202,7 @@ void request_clipboard(int clipboardtypeid) {
201202

202203
// Clipboard funcs
203204

204-
void set_clipboard(int clipboardtypeid, void *data) {
205+
void set_clipboard(int clipboardtypeid, gpointer data) {
205206
GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
206207
gtk_clipboard_set_text(clipboard, data, -1); // TODO text only
207208
}
@@ -217,6 +218,18 @@ void top_signal_connect() {
217218
g_signal_connect(top, "scroll-event", G_CALLBACK(s_scroll), NULL);
218219
}
219220

221+
void top_signal_disconnect() {
222+
g_signal_handlers_disconnect_by_func(top, G_CALLBACK(on_delete), NULL);
223+
g_signal_handlers_disconnect_by_func(top, G_CALLBACK(s_keypress), NULL);
224+
g_signal_handlers_disconnect_by_func(top, G_CALLBACK(s_button), NULL);
225+
g_signal_handlers_disconnect_by_func(top, G_CALLBACK(s_motion), NULL);
226+
g_signal_handlers_disconnect_by_func(top, G_CALLBACK(s_scroll), NULL);
227+
}
228+
220229
void layout_signal_connect(GtkWidget *layout) {
221230
g_signal_connect(layout, "size-allocate", G_CALLBACK(on_size_allocate), NULL);
222231
}
232+
233+
void layout_signal_disconnect(GtkWidget *layout) {
234+
g_signal_handlers_disconnect_by_func(layout, G_CALLBACK(on_size_allocate), NULL);
235+
}

four/call.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,13 @@ static void commandVersion() {
1111
// exit
1212

1313
static void commandExit(pipe_buffer *target) {
14+
static int exitCount = 0;
15+
if (exitCount++ == 0) {
16+
top_signal_disconnect();
17+
}
1418
io_stop(target);
1519
if (io_exited()) {
20+
gtk_window_destroy(GTK_WINDOW(top));
1621
g_application_quit(G_APPLICATION(app));
1722
}
1823
}

four/event.c

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include "glib-object.h"
12
#include "terminal.h"
23
#include <gtk/gtk.h>
34

@@ -48,7 +49,7 @@ static void write_configure_event_once(configure_event *e) {
4849
static int idle_count = 0;
4950
static GtkWidget *inner_size_widget = NULL;
5051

51-
static void on_configure_event(gpointer user_data) {
52+
static void on_configure_event(gpointer data) {
5253
int inner_width = gtk_widget_get_width(inner_size_widget);
5354
int inner_height = gtk_widget_get_height(inner_size_widget);
5455
if (inner_width == 0 && inner_height == 0) {
@@ -64,25 +65,25 @@ static void on_configure_event(gpointer user_data) {
6465
write_configure_event_once(&e);
6566
}
6667

67-
static gboolean idle_func(gpointer user_data) {
68+
static gboolean idle_func(gpointer data) {
6869
idle_count--;
6970
if (idle_count > 0) {
7071
return G_SOURCE_CONTINUE;
7172
}
72-
on_configure_event(user_data);
73+
on_configure_event(data);
7374
return G_SOURCE_REMOVE;
7475
}
7576

76-
static void size_notify(GObject *self, GParamSpec *pspec, gpointer user_data) {
77+
static void size_notify(GObject *self, GParamSpec *pspec, gpointer data) {
7778
if (idle_count <= 0) {
78-
g_idle_add(idle_func, user_data);
79+
g_idle_add(idle_func, data);
7980
}
8081
idle_count++;
8182
}
8283

83-
static void adjustment_notify(GtkAdjustment *self, gpointer user_data) {
84+
static void adjustment_notify(GtkAdjustment *self, gpointer data) {
8485
if (idle_count <= 0) {
85-
g_idle_add(idle_func, user_data);
86+
g_idle_add(idle_func, data);
8687
}
8788
idle_count++;
8889
}
@@ -100,7 +101,7 @@ typedef struct {
100101
_Static_assert(sizeof(keyboard_event) == 8, "wrong keyboard_event align");
101102

102103
static gboolean key_pressed(GtkEventControllerKey *self, guint keyval, guint keycode, GdkModifierType state,
103-
gpointer user_data) {
104+
gpointer data) {
104105
char command_type = 'k';
105106
keyboard_event e;
106107
e.unicode = gdk_keyval_to_unicode(keyval);
@@ -142,7 +143,7 @@ static int buttonType(int n_press) {
142143
static guint32 prev_button_time = 0;
143144
static GdkEventType prev_button_type = 0;
144145

145-
static void button_pressed(GtkGestureClick *self, gint n_press, gdouble x, gdouble y, gpointer user_data) {
146+
static void button_pressed(GtkGestureClick *self, gint n_press, gdouble x, gdouble y, gpointer data) {
146147
GdkEvent *event = gtk_event_controller_get_current_event(GTK_EVENT_CONTROLLER(self));
147148
if (gdk_event_get_time(event) == prev_button_time && gdk_event_get_event_type(event) == prev_button_type) {
148149
return;
@@ -160,7 +161,7 @@ static void button_pressed(GtkGestureClick *self, gint n_press, gdouble x, gdoub
160161
pipe_event_flush();
161162
}
162163

163-
static void button_released(GtkGestureClick *self, gint n_press, gdouble x, gdouble y, gpointer user_data) {
164+
static void button_released(GtkGestureClick *self, gint n_press, gdouble x, gdouble y, gpointer data) {
164165
GdkEvent *event = gtk_event_controller_get_current_event(GTK_EVENT_CONTROLLER(self));
165166
if (gdk_event_get_time(event) == prev_button_time && gdk_event_get_event_type(event) == prev_button_type) {
166167
return;
@@ -188,7 +189,7 @@ typedef struct {
188189

189190
_Static_assert(sizeof(motion_event) == 8, "wrong motion_event align");
190191

191-
static void motion_notify(GtkEventControllerMotion *self, gdouble x, gdouble y, gpointer user_data) {
192+
static void motion_notify(GtkEventControllerMotion *self, gdouble x, gdouble y, gpointer data) {
192193
GdkEvent *event = gtk_event_controller_get_current_event(GTK_EVENT_CONTROLLER(self));
193194
if (gdk_event_get_time(event) == prev_button_time && gdk_event_get_event_type(event) == prev_button_type) {
194195
return;
@@ -216,7 +217,7 @@ typedef struct {
216217

217218
_Static_assert(sizeof(scroll_event) == 6, "wrong scroll_event align");
218219

219-
static gboolean scroll_notify(GtkEventControllerScroll *self, gdouble dx, gdouble dy, gpointer user_data) {
220+
static gboolean scroll_notify(GtkEventControllerScroll *self, gdouble dx, gdouble dy, gpointer data) {
220221
char command_type = 's';
221222
scroll_event e;
222223
e.direction = 4;
@@ -276,30 +277,51 @@ void set_clipboard(int clipboardtypeid, void *data) {
276277

277278
void top_signal_connect() { g_signal_connect(top, "close-request", G_CALLBACK(on_delete), NULL); }
278279

280+
void top_signal_disconnect() { g_signal_handlers_disconnect_by_func(top, G_CALLBACK(on_delete), NULL); }
281+
282+
static GtkEventController *keyEventController;
283+
static GtkGesture *getstureConroller;
284+
static GtkEventController *motionEventController;
285+
static GtkEventController *scrollEventController;
286+
279287
void layout_signal_connect(GtkWidget *scrolled, GtkAdjustment *adjustment) {
280288
inner_size_widget = scrolled;
281289
g_signal_connect(top, "notify::default-width", G_CALLBACK(size_notify), NULL);
282290
g_signal_connect(top, "notify::default-height", G_CALLBACK(size_notify), NULL);
283291
g_signal_connect(adjustment, "changed", G_CALLBACK(adjustment_notify), NULL);
284292
g_signal_connect(adjustment, "value-changed", G_CALLBACK(adjustment_notify), NULL);
285293

286-
GtkEventController *keyEventController = gtk_event_controller_key_new();
294+
keyEventController = gtk_event_controller_key_new();
287295
g_signal_connect(keyEventController, "key-pressed", G_CALLBACK(key_pressed), NULL);
288296
gtk_widget_add_controller(scrolled, keyEventController);
289297

290-
GtkGesture *getstureConroller = gtk_gesture_click_new();
298+
getstureConroller = gtk_gesture_click_new();
291299
gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(getstureConroller), 0);
292300
gtk_gesture_single_set_touch_only(GTK_GESTURE_SINGLE(getstureConroller), FALSE);
293301
g_signal_connect(getstureConroller, "pressed", G_CALLBACK(button_pressed), NULL);
294302
g_signal_connect(getstureConroller, "released", G_CALLBACK(button_released), NULL);
295303
g_signal_connect(getstureConroller, "unpaired-release", G_CALLBACK(button_released), NULL);
296304
gtk_widget_add_controller(scrolled, GTK_EVENT_CONTROLLER(getstureConroller));
297305

298-
GtkEventController *motionEventController = gtk_event_controller_motion_new();
306+
motionEventController = gtk_event_controller_motion_new();
299307
g_signal_connect(motionEventController, "motion", G_CALLBACK(motion_notify), NULL);
300308
gtk_widget_add_controller(scrolled, motionEventController);
301309

302-
GtkEventController *scrollEventController = gtk_event_controller_scroll_new(GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES);
310+
scrollEventController = gtk_event_controller_scroll_new(GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES);
303311
g_signal_connect(scrollEventController, "scroll", G_CALLBACK(scroll_notify), NULL);
304312
gtk_widget_add_controller(scrolled, scrollEventController);
305313
}
314+
315+
void layout_signal_disconnect(GtkWidget *scrolled, GtkAdjustment *adjustment) {
316+
g_signal_handlers_disconnect_by_func(top, G_CALLBACK(size_notify), NULL);
317+
g_signal_handlers_disconnect_by_func(adjustment, G_CALLBACK(adjustment_notify), NULL);
318+
319+
g_signal_handlers_disconnect_by_func(keyEventController, G_CALLBACK(key_pressed), NULL);
320+
321+
g_signal_handlers_disconnect_by_func(getstureConroller, G_CALLBACK(button_pressed), NULL);
322+
g_signal_handlers_disconnect_by_func(getstureConroller, G_CALLBACK(button_released), NULL);
323+
324+
g_signal_handlers_disconnect_by_func(motionEventController, G_CALLBACK(motion_notify), NULL);
325+
326+
g_signal_handlers_disconnect_by_func(scrollEventController, G_CALLBACK(scroll_notify), NULL);
327+
}

four/layout.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include "glib-object.h"
12
#include "terminal.h"
23
#include <gtk/gtk.h>
34

@@ -41,8 +42,11 @@ static void layout_main_create(int id) {
4142
static void layout_main_destroy(int id) {
4243
layout_main *l = g_hash_table_lookup(layout_table, GINT_TO_POINTER(id));
4344
g_hash_table_remove(layout_table, GINT_TO_POINTER(id));
44-
// gtk_widget_unparent(l->layout);
45-
// gtk_widget_unparent(l->scrolled);
45+
layout_signal_disconnect(l->scrolled, l->adjustment);
46+
gtk_scrolled_window_set_hadjustment(GTK_SCROLLED_WINDOW(l->scrolled), NULL);
47+
gtk_scrolled_window_set_vadjustment(GTK_SCROLLED_WINDOW(l->scrolled), NULL);
48+
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(l->scrolled), NULL);
49+
gtk_window_set_child(GTK_WINDOW(top), NULL);
4650
g_free(l);
4751
}
4852

@@ -62,7 +66,7 @@ static void layout_node_create(int id, int parent_id) {
6266
l->layout = gtk_fixed_new();
6367
gtk_widget_set_overflow(l->layout, GTK_OVERFLOW_HIDDEN);
6468
l->parent = layout_get_widget(parent_id);
65-
gtk_widget_set_parent(l->layout, l->parent);
69+
gtk_fixed_put(GTK_FIXED(l->parent), l->layout, 0, 0);
6670
l->x = 0;
6771
l->y = 0;
6872
gtk_widget_set_visible(l->layout, TRUE);
@@ -72,7 +76,7 @@ static void layout_node_create(int id, int parent_id) {
7276
static void layout_node_destroy(int id) {
7377
layout_elem *l = g_hash_table_lookup(layout_table, GINT_TO_POINTER(id));
7478
g_hash_table_remove(layout_table, GINT_TO_POINTER(id));
75-
gtk_widget_unparent(l->layout);
79+
gtk_fixed_remove(GTK_FIXED(l->parent), l->layout);
7680
g_free(l);
7781
}
7882

@@ -87,10 +91,9 @@ static void layout_node_size(int id, int x, int y, int width, int height) {
8791
static void layout_node_raise(int id) {
8892
layout_elem *l = g_hash_table_lookup(layout_table, GINT_TO_POINTER(id));
8993
g_object_ref(l->layout);
90-
gtk_widget_unparent(l->layout);
91-
gtk_widget_set_parent(l->layout, l->parent);
94+
gtk_fixed_remove(GTK_FIXED(l->parent), l->layout);
95+
gtk_fixed_put(GTK_FIXED(l->parent), l->layout, l->x, l->y);
9296
g_object_unref(l->layout);
93-
gtk_fixed_move(GTK_FIXED(l->parent), l->layout, l->x, l->y);
9497
}
9598

9699
GtkWidget *layout_get_widget(int id) {

four/main.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,7 @@ static void on_app_activate(GApplication *application, gpointer data) {
1919
pipe_init(pipe_suffix);
2020
}
2121

22-
static void on_app_shutdown(GApplication *application, gpointer data) {
23-
pipe_done();
24-
// gtk_window_destroy(GTK_WINDOW(top));
25-
// g_application_quit(G_APPLICATION(app));
26-
}
22+
static void on_app_shutdown(GApplication *application, gpointer data) { pipe_done(); }
2723

2824
int main(int argc, char **argv) {
2925
if (argc != 2) {
@@ -42,6 +38,10 @@ int main(int argc, char **argv) {
4238
g_signal_connect(app, "shutdown", G_CALLBACK(on_app_shutdown), NULL);
4339

4440
int status = g_application_run(G_APPLICATION(app), 1, argv);
41+
42+
g_signal_handlers_disconnect_by_func(app, G_CALLBACK(on_app_activate), NULL);
43+
g_signal_handlers_disconnect_by_func(app, G_CALLBACK(on_app_shutdown), NULL);
44+
4545
g_object_unref(app);
4646
return status;
4747
}

four/pipe.c

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ static FILE *pipe_open(char *name, char *suffix, char *filemode) {
2323
return handle;
2424
}
2525

26+
static void pipe_close(FILE *handle) {
27+
if (fclose(handle) != 0) {
28+
perror("pipe close failed");
29+
exit(EXIT_FAILURE);
30+
}
31+
}
32+
2633
void pipe_init(char *pipe_suffix) {
2734
handle_output = pipe_open(FIFO_OUTPUT_PATH, pipe_suffix, "w");
2835
handle_event = pipe_open(FIFO_EVENT_PATH, pipe_suffix, "w");
@@ -33,22 +40,10 @@ void pipe_init(char *pipe_suffix) {
3340
}
3441

3542
void pipe_done() {
36-
if (fclose(handle_input) != 0) {
37-
perror("pipe close failed (i)");
38-
exit(EXIT_FAILURE);
39-
}
40-
if (fclose(handle_stream) != 0) {
41-
perror("pipe close failed (s)");
42-
exit(EXIT_FAILURE);
43-
}
44-
if (fclose(handle_output) != 0) {
45-
perror("pipe close failed (o)");
46-
exit(EXIT_FAILURE);
47-
}
48-
if (fclose(handle_event) != 0) {
49-
perror("pipe close failed (e)");
50-
exit(EXIT_FAILURE);
51-
}
43+
pipe_close(handle_input);
44+
pipe_close(handle_stream);
45+
pipe_close(handle_output);
46+
pipe_close(handle_event);
5247
}
5348

5449
void pipe_output_write(const void *data, const int length) {

four/terminal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ gboolean io_exited();
3636
// event
3737

3838
void top_signal_connect();
39+
void top_signal_disconnect();
3940
void layout_signal_connect(GtkWidget *scrolled, GtkAdjustment *adjustment);
41+
void layout_signal_disconnect(GtkWidget *scrolled, GtkAdjustment *adjustment);
4042

4143
void s_menu_action(char *action);
4244
void request_clipboard(int clipboardtypeid);

four/window.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ void window_create(int id, int layout_id) {
2424
w->y = 0;
2525
w->draw_list = g_ptr_array_new_with_free_func(elem_draw_destroy);
2626
gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(w->draw), draw_callback, w->draw_list, NULL);
27-
gtk_widget_set_parent(w->draw, w->layout);
27+
gtk_fixed_put(GTK_FIXED(w->layout), w->draw, 0, 0);
2828
gtk_widget_set_visible(w->draw, TRUE);
2929
if (window_table == NULL) {
3030
window_table = g_hash_table_new(g_direct_hash, g_direct_equal);
@@ -36,7 +36,7 @@ void window_destroy(int id) {
3636
window_elem *w = g_hash_table_lookup(window_table, GINT_TO_POINTER(id));
3737
g_hash_table_remove(window_table, GINT_TO_POINTER(id));
3838
g_ptr_array_free(w->draw_list, TRUE);
39-
gtk_widget_unparent(w->draw);
39+
gtk_fixed_remove(GTK_FIXED(w->layout), w->draw);
4040
g_free(w);
4141
}
4242

@@ -62,10 +62,9 @@ void window_size(int id, int x, int y, int width, int height) {
6262
void window_raise(int id) {
6363
window_elem *w = g_hash_table_lookup(window_table, GINT_TO_POINTER(id));
6464
g_object_ref(w->draw);
65-
gtk_widget_unparent(w->draw);
66-
gtk_widget_set_parent(w->draw, w->layout);
65+
gtk_fixed_remove(GTK_FIXED(w->layout), w->draw);
66+
gtk_fixed_put(GTK_FIXED(w->layout), w->draw, w->x, w->y);
6767
g_object_unref(w->draw);
68-
gtk_fixed_move(GTK_FIXED(w->layout), w->draw, w->x, w->y);
6968
}
7069

7170
void window_redraw(int id) {

layout.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ void layout_create(int id, int parent_id) {
3939
void layout_destroy(int id) {
4040
layout_elem *l = g_hash_table_lookup(layout_table, GINT_TO_POINTER(id));
4141
g_hash_table_remove(layout_table, GINT_TO_POINTER(id));
42+
if (id == 1) {
43+
layout_signal_disconnect(l->layout);
44+
}
4245
gtk_widget_destroy(GTK_WIDGET(l->layout));
4346
g_free(l);
4447
}

0 commit comments

Comments
 (0)