Merge lp:~arthurborsboom/xpad/xpad-4.2 into lp:xpad

Proposed by Arthur Borsboom
Status: Merged
Merged at revision: 649
Proposed branch: lp:~arthurborsboom/xpad/xpad-4.2
Merge into: lp:xpad
Diff against target: 629 lines (+385/-15)
9 files modified
src/xpad-app.c (+16/-3)
src/xpad-app.h (+1/-0)
src/xpad-pad-group.c (+6/-0)
src/xpad-pad-group.h (+1/-0)
src/xpad-pad.c (+47/-11)
src/xpad-pad.h (+3/-0)
src/xpad-periodic.c (+268/-0)
src/xpad-periodic.h (+42/-0)
src/xpad-tray.c (+1/-1)
To merge this branch: bzr merge lp:~arthurborsboom/xpad/xpad-4.2
Reviewer Review Type Date Requested Status
Arthur Borsboom Approve
Review via email: mp+190152@code.launchpad.net

Description of the change

Performance fix: Busy harddisk while typing or moving pad

To post a comment you must log in.
Revision history for this message
Arthur Borsboom (arthurborsboom) :
review: Approve
lp:~arthurborsboom/xpad/xpad-4.2 updated
649. By Arthur Borsboom

performance fix: busy harddisk while typing or moving pad

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/xpad-app.c'
2--- src/xpad-app.c 2009-05-11 12:29:11 +0000
3+++ src/xpad-app.c 2013-10-09 14:52:00 +0000
4@@ -40,6 +40,7 @@
5 #include "xpad-app.h"
6 #include "xpad-pad.h"
7 #include "xpad-pad-group.h"
8+#include "xpad-periodic.h"
9 #include "xpad-session-manager.h"
10 #include "xpad-tray.h"
11
12@@ -168,6 +169,11 @@
13
14 xpad_tray_open ();
15 xpad_session_manager_init ();
16+
17+ /* Initialize Xpad-periodic module */
18+ Xpad_periodic_init();
19+ Xpad_periodic_set_callback("save-content", (XpadPeriodicFunc) xpad_pad_save_content);
20+ Xpad_periodic_set_callback("save-info", (XpadPeriodicFunc) xpad_pad_save_info);
21
22 /* load all pads */
23 pads_loaded_on_start = xpad_app_load_pads ();
24@@ -244,6 +250,13 @@
25 return pad_group;
26 }
27
28+void
29+xpad_app_quit (void)
30+{
31+ xpad_pad_group_save_unsaved_all(xpad_app_get_pad_group());
32+ gtk_main_quit();
33+}
34+
35 gboolean
36 xpad_app_get_translucent (void)
37 {
38@@ -393,7 +406,7 @@
39 if (num_pads == 0)
40 {
41 if (gtk_main_level () > 0)
42- gtk_main_quit ();
43+ xpad_app_quit ();
44 else
45 exit (0);
46 }
47@@ -420,7 +433,7 @@
48 else
49 {
50 if (gtk_main_level () > 0)
51- gtk_main_quit ();
52+ xpad_app_quit ();
53 else
54 exit (0);
55 }
56@@ -876,7 +889,7 @@
57 if (option_quit)
58 {
59 if (have_gtk && gtk_main_level () > 0)
60- gtk_main_quit ();
61+ xpad_app_quit ();
62 else
63 exit (0);
64 }
65
66=== modified file 'src/xpad-app.h'
67--- src/xpad-app.h 2008-09-21 00:03:40 +0000
68+++ src/xpad-app.h 2013-10-09 14:52:00 +0000
69@@ -31,6 +31,7 @@
70 G_CONST_RETURN gchar *xpad_app_get_program_path (void);
71 XpadPadGroup *xpad_app_get_pad_group (void);
72 gboolean xpad_app_get_translucent (void);
73+void xpad_app_quit (void);
74
75 G_END_DECLS
76
77
78=== modified file 'src/xpad-pad-group.c'
79--- src/xpad-pad-group.c 2009-05-11 12:29:11 +0000
80+++ src/xpad-pad-group.c 2013-10-09 14:52:00 +0000
81@@ -168,6 +168,12 @@
82 g_slist_foreach (group->priv->pads, (GFunc) xpad_pad_close, NULL);
83 }
84
85+void
86+xpad_pad_group_save_unsaved_all (XpadPadGroup *group)
87+{
88+ if (group)
89+ g_slist_foreach (group->priv->pads, (GFunc) xpad_pad_save_unsaved, NULL);
90+}
91
92 void
93 xpad_pad_group_show_all (XpadPadGroup *group)
94
95=== modified file 'src/xpad-pad-group.h'
96--- src/xpad-pad-group.h 2008-09-21 00:03:40 +0000
97+++ src/xpad-pad-group.h 2013-10-09 14:52:00 +0000
98@@ -63,6 +63,7 @@
99 void xpad_pad_group_toggle_hide (XpadPadGroup *group);
100 GSList * xpad_pad_group_get_pads (XpadPadGroup *group);
101 gint xpad_pad_group_num_visible_pads (XpadPadGroup *group);
102+void xpad_pad_group_save_unsaved_all (XpadPadGroup *group);
103
104 G_END_DECLS
105
106
107=== modified file 'src/xpad-pad.c'
108--- src/xpad-pad.c 2011-11-16 18:10:04 +0000
109+++ src/xpad-pad.c 2013-10-09 14:52:00 +0000
110@@ -31,6 +31,7 @@
111 #include "xpad-app.h"
112 #include "xpad-pad.h"
113 #include "xpad-pad-properties.h"
114+#include "xpad-periodic.h"
115 #include "xpad-preferences.h"
116 #include "xpad-settings.h"
117 #include "xpad-text-buffer.h"
118@@ -67,6 +68,9 @@
119 /* menus */
120 GtkWidget *menu;
121 GtkWidget *highlight_menu;
122+
123+ gboolean unsaved_content;
124+ gboolean unsaved_info;
125
126 XpadPadGroup *group;
127 };
128@@ -242,6 +246,8 @@
129 pad->priv->toolbar_expanded = FALSE;
130 pad->priv->toolbar_pad_resized = TRUE;
131 pad->priv->properties = NULL;
132+ pad->priv->unsaved_content = TRUE;
133+ pad->priv->unsaved_info = TRUE;
134 pad->priv->group = NULL;
135
136 XpadTextView *text_view = g_object_new (XPAD_TYPE_TEXT_VIEW,
137@@ -785,7 +791,7 @@
138 pango_font_description_free (fontdesc);
139 }
140
141- xpad_pad_save_info (pad);
142+ xpad_save_info_delayed (pad);
143 }
144
145 static void
146@@ -801,7 +807,7 @@
147 gtk_widget_modify_text (pad->priv->textview, GTK_STATE_NORMAL, xpad_pad_properties_get_text_color (prop));
148 }
149
150- xpad_pad_save_info (pad);
151+ xpad_save_info_delayed (pad);
152 }
153
154 static void
155@@ -811,7 +817,7 @@
156
157 gtk_widget_modify_text (pad->priv->textview, GTK_STATE_NORMAL, xpad_pad_properties_get_text_color (prop));
158
159- xpad_pad_save_info (pad);
160+ xpad_save_info_delayed (pad);
161 }
162
163 static void
164@@ -821,7 +827,7 @@
165
166 gtk_widget_modify_base (pad->priv->textview, GTK_STATE_NORMAL, xpad_pad_properties_get_back_color (prop));
167
168- xpad_pad_save_info (pad);
169+ xpad_save_info_delayed (pad);
170 }
171
172 static void
173@@ -837,7 +843,7 @@
174 if (fontdesc)
175 pango_font_description_free (fontdesc);
176
177- xpad_pad_save_info (pad);
178+ xpad_save_info_delayed (pad);
179 }
180
181 static void
182@@ -891,7 +897,7 @@
183 static void
184 xpad_pad_quit (XpadPad *pad)
185 {
186- gtk_main_quit ();
187+ xpad_app_quit ();
188 }
189
190 static void
191@@ -901,7 +907,7 @@
192 xpad_pad_sync_title (pad);
193
194 /* record change */
195- xpad_pad_save_content (pad);
196+ xpad_save_content_delayed(pad);
197 }
198
199 static gboolean
200@@ -926,7 +932,7 @@
201 pad->priv->height = event->height;
202 pad->priv->location_valid = TRUE;
203
204- xpad_pad_save_info (pad);
205+ xpad_save_content_delayed(pad);
206
207 /* Sometimes when moving, if the toolbar tries to hide itself,
208 the window manager will not resize it correctly. So, we make
209@@ -1138,6 +1144,7 @@
210 xpad_text_buffer_thaw_undo (XPAD_TEXT_BUFFER (buffer));
211
212 xpad_pad_text_changed(pad, buffer);
213+ pad->priv->unsaved_content = FALSE;
214 }
215
216 void
217@@ -1160,7 +1167,8 @@
218 content = xpad_text_buffer_get_text_with_tags (XPAD_TEXT_BUFFER (buffer));
219
220 fio_set_file (pad->priv->contentname, content);
221-
222+
223+ pad->priv->unsaved_content = FALSE;
224 g_free (content);
225 }
226
227@@ -1195,6 +1203,8 @@
228 "s|content", &pad->priv->contentname,
229 NULL))
230 return;
231+
232+ pad->priv->unsaved_info = FALSE;
233
234 pad->priv->location_valid = TRUE;
235 if (xpad_settings_get_has_toolbar (xpad_settings ()) &&
236@@ -1302,7 +1312,8 @@
237 "s|fontname", fontname,
238 "s|content", pad->priv->contentname,
239 NULL);
240-
241+
242+ pad->priv->unsaved_info = FALSE;
243 g_free (fontname);
244 }
245
246@@ -1476,7 +1487,7 @@
247 XpadTextBuffer *buffer = NULL;
248 buffer = XPAD_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)));
249 xpad_text_buffer_toggle_tag (buffer, name);
250- xpad_pad_save_content (pad);
251+ xpad_save_content_delayed(pad);
252 }
253
254 static void
255@@ -1877,3 +1888,28 @@
256 else
257 gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ());
258 }
259+
260+/* These functions below are used to reduce the amounts of writes, hence improve the performance. */
261+void xpad2_save_content (void * vptr)
262+{
263+ xpad_pad_save_content(vptr);
264+}
265+void xpad_save_content_delayed (XpadPad *pad)
266+{
267+ pad->priv->unsaved_content = TRUE;
268+ Xpad_periodic_save_content_delayed(pad);
269+}
270+void xpad_save_info_delayed (XpadPad *pad)
271+{
272+ pad->priv->unsaved_info = TRUE;
273+ Xpad_periodic_save_info_delayed(pad);
274+}
275+void xpad_pad_save_unsaved (XpadPad *pad)
276+{
277+ if(pad->priv->unsaved_content == TRUE) {
278+ xpad_pad_save_content(pad);
279+ }
280+ if(pad->priv->unsaved_info == TRUE) {
281+ xpad_pad_save_info(pad);
282+ }
283+}
284
285=== modified file 'src/xpad-pad.h'
286--- src/xpad-pad.h 2011-11-16 18:10:04 +0000
287+++ src/xpad-pad.h 2013-10-09 14:52:00 +0000
288@@ -64,6 +64,9 @@
289
290 void xpad_pad_load_content (XpadPad *pad);
291 void xpad_pad_save_content (XpadPad *pad);
292+void xpad_pad_save_unsaved (XpadPad *pad);
293+void xpad_save_content_delayed (XpadPad *pad);
294+void xpad_save_info_delayed (XpadPad *pad);
295
296 void xpad_pad_notify_has_selection (XpadPad *pad);
297 void xpad_pad_notify_clipboard_owner_changed (XpadPad *pad);
298
299=== added file 'src/xpad-periodic.c'
300--- src/xpad-periodic.c 1970-01-01 00:00:00 +0000
301+++ src/xpad-periodic.c 2013-10-09 14:52:00 +0000
302@@ -0,0 +1,268 @@
303+
304+#include <stdlib.h>
305+#include <stdio.h>
306+#include <string.h>
307+#include <stdarg.h>
308+#include "xpad-periodic.h"
309+
310+#ifdef SHOW_DEBUG
311+# define G_PRINT_DBG g_print
312+#else
313+# define G_PRINT_DBG gprint_ignore
314+#endif
315+
316+#define TIMEOUT_SECONDS 4
317+
318+struct sigref_ {
319+ const char * signame;
320+ XpadPeriodicFunc func_ptr;
321+ gpointer data;
322+};
323+
324+typedef struct sigref_ Xpadsigref;
325+
326+typedef struct {
327+ /************************
328+ count = a clock tick count
329+ after_id = the timeout id
330+ ************************/
331+ int count;
332+ int after_id;
333+
334+ /************************
335+ template = a list of signal names and function pointers
336+ template_len = the length of 'template'
337+ sigs = a list of signal names, function pointers and data
338+ sigs_len = the length of 'sigs'
339+ ************************/
340+ Xpadsigref * template;
341+ int template_len;
342+ Xpadsigref * sigs;
343+ int sigs_len;
344+} XpadPeriodic;
345+
346+
347+/* prototypes */
348+static gint xppd_intercept (gpointer);
349+static gint gprint_ignore(const char *, ...);
350+
351+static void xpad_sigref_dump2 (gint);
352+static gboolean str_equal (const char *, const char *);
353+
354+/* global variables */
355+static XpadPeriodic xpptr [1];
356+
357+/* Functions start here */
358+
359+gboolean Xpad_periodic_init (void)
360+{
361+ memset(xpptr, 0, sizeof(*xpptr));
362+ xpptr->after_id =
363+ g_timeout_add_seconds(TIMEOUT_SECONDS, xppd_intercept, xpptr);
364+
365+ /* Allocate space for the signal references. */
366+ int tlen = xpptr->template_len = 5;
367+ int slen = xpptr->sigs_len = 20;
368+ xpptr->template = g_malloc0(tlen * sizeof(Xpadsigref));
369+ xpptr->sigs = g_malloc0(slen * sizeof(Xpadsigref));
370+
371+ return TRUE;
372+}
373+
374+void Xpad_periodic_close (void)
375+{
376+ if (xpptr->after_id) { g_source_remove(xpptr->after_id); }
377+ /* Free the signal references memory. */
378+ g_free(xpptr->template);
379+ g_free(xpptr->sigs);
380+ /* Signal that this structure is now cleared. */
381+ memset(xpptr, 0, sizeof(*xpptr));
382+}
383+
384+/************************
385+xppd_intercept - intercepts a timer tick
386+
387+ This function intercepts a timer tick and iterates
388+ over the signal references. Any signal references that
389+ are fully stocked with signal names, function pointers
390+ and data pointers are invoked.
391+
392+ IOW (In other words), the function pointer is called with the
393+ right data pointer.
394+************************/
395+gint xppd_intercept (gpointer cdata)
396+{
397+ int cnt=0;
398+ XpadPeriodicFunc fnptr=0;
399+ xpptr->count++; /* increment tick count */
400+
401+ G_PRINT_DBG("xppd tick: %4d\n", xpptr->count);
402+
403+ for (cnt = 0; cnt < xpptr->sigs_len; ++cnt) {
404+ Xpadsigref * sig_item = xpptr->sigs + cnt;
405+ if (sig_item->signame && sig_item->func_ptr && sig_item->data) {
406+ fnptr = sig_item->func_ptr;
407+ (*fnptr)(sig_item->data);
408+ G_PRINT_DBG("invoked %s : %p : %p\n", sig_item->signame,
409+ sig_item->func_ptr, sig_item->data);
410+ memset(sig_item, 0, sizeof(*sig_item));
411+ }
412+ }
413+
414+ return TRUE;
415+}
416+
417+/************************
418+ Xpad_periodic_set_callback():
419+ This function prepares a callback function to be invoked
420+ for an event name such as "save-content" or "save-info".
421+
422+ cbname : event name (or callback function name)
423+ func : function address
424+
425+ Returns true if a callback was registered.
426+************************/
427+gboolean Xpad_periodic_set_callback (
428+ const char * cbname,
429+ XpadPeriodicFunc func)
430+{
431+ int index = 0;
432+ gboolean isdone=FALSE;
433+ if (0 == func) { return FALSE; }
434+ if (0 == cbname || 0==*cbname) { return FALSE; }
435+
436+ /* Find an open slot for signal (callback) references and
437+ insert this one. */
438+ for (index = 0; index < xpptr->template_len; ++index) {
439+ /* Store a pointer to the current signal item. */
440+ Xpadsigref * sig_item = xpptr->template + index;
441+
442+ /* If it's empty, set it. */
443+ if (0 == sig_item->signame) {
444+ sig_item->signame = cbname;
445+ sig_item->func_ptr = func;
446+ isdone = TRUE;
447+ break;
448+ }
449+ }
450+
451+ if (! isdone) {
452+ printf("Failed to install signal callback: %s\n", cbname);
453+ exit(1);
454+ }
455+
456+ return isdone;
457+}
458+
459+void Xpad_periodic_save_info_delayed (void * xpad_pad)
460+{
461+ Xpad_periodic_signal("save-info", xpad_pad);
462+}
463+
464+void Xpad_periodic_save_content_delayed (void * xpad_pad)
465+{
466+ Xpad_periodic_signal("save-content", xpad_pad);
467+}
468+
469+void Xpad_periodic_signal (const char * cbname, void * xpad_pad)
470+{
471+ int isdone = 0;
472+ int tnx=0, snx=0;
473+ XpadPeriodicFunc func_ptr = 0;
474+ Xpadsigref * sig_item = 0;
475+
476+ if (0 == cbname || 0==*cbname) { return; }
477+ if (0 == xpad_pad) { return; }
478+
479+ /* Get the callback function address */
480+ for (tnx = 0; tnx < xpptr->template_len; ++tnx) {
481+ if (str_equal(xpptr->template[tnx].signame, cbname)) {
482+ func_ptr = xpptr->template[tnx].func_ptr;
483+ break;
484+ }
485+ }
486+
487+ /* If there is no callback address, we can't continue. */
488+ if (! func_ptr) {
489+ Xpad_periodic_error_exit("Can't find signal function address: %s\n", cbname);
490+ }
491+
492+ /* Check that this event is not already present.
493+ If it is present, don't do anything more. */
494+ for (snx = 0; snx < xpptr->sigs_len; ++snx) {
495+ sig_item = xpptr->sigs + snx;
496+ if (str_equal(sig_item->signame,cbname) &&
497+ (xpad_pad == sig_item->data)) {
498+ G_PRINT_DBG("Already got signal: %s\n", cbname);
499+ return;
500+ }
501+ }
502+
503+ /* Find a suitable slot for the signal reference and set it. */
504+ for (snx = 0; snx < xpptr->sigs_len; ++snx) {
505+ gint doadd = 0;
506+ sig_item = xpptr->sigs + snx;
507+
508+ doadd += (str_equal(sig_item->signame, cbname));
509+ doadd += (0 == sig_item->signame);
510+
511+ if (doadd) {
512+ sig_item->signame = cbname;
513+ sig_item->func_ptr = func_ptr;
514+ sig_item->data = xpad_pad;
515+ isdone = TRUE;
516+ break;
517+ }
518+ }
519+
520+ if (! isdone) {
521+ Xpad_periodic_error_exit("Could not schedule event: %s\n", cbname);
522+ }
523+}
524+
525+gboolean str_equal (const char * s1, const char * s2) {
526+ if (0 == s1 || 0==s2) { return FALSE; }
527+ if (s1 == s2) { return TRUE; }
528+ return (0 == strcmp(s1, s2));
529+}
530+
531+gint gprint_ignore (const char * fmt, ...)
532+{
533+ return 0;
534+}
535+
536+void xpad_sigref_dump2 (gint twhich)
537+{
538+ int tlen = 0, cnt = 0;
539+ Xpadsigref * xlist = 0;
540+ if (0 == twhich) { xlist = xpptr->template; }
541+ if (1 == twhich) { xlist = xpptr->sigs; }
542+ if (0 == twhich) { tlen = xpptr->template_len; }
543+ if (1 == twhich) { tlen = xpptr->sigs_len; }
544+
545+ for (cnt = 0; cnt < tlen; ++cnt) {
546+ Xpadsigref * xitem = xlist + cnt;
547+ if (0 == xitem->signame) { continue; }
548+ printf("%3d: %s : %p : %p\n", cnt, xitem->signame,
549+ xitem->func_ptr, xitem->data);
550+ }
551+}
552+
553+void Xpad_periodic_error_exit (const char * fmt, ...)
554+{
555+ va_list app;
556+ va_start(app, fmt);
557+ vprintf(fmt, app);
558+ va_end(app);
559+ exit(1);
560+}
561+
562+void Xpad_periodic_test (void)
563+{
564+ puts("Template:");
565+ xpad_sigref_dump2(0);
566+ exit(0);
567+}
568+
569+
570+/* vim: set ts=4 sw=4 :vim */
571
572=== added file 'src/xpad-periodic.h'
573--- src/xpad-periodic.h 1970-01-01 00:00:00 +0000
574+++ src/xpad-periodic.h 2013-10-09 14:52:00 +0000
575@@ -0,0 +1,42 @@
576+
577+#ifndef XPAD_PERIODIC_H
578+#define XPAD_PERIODIC_H
579+
580+#include <gtk/gtk.h>
581+
582+typedef void (*XpadPeriodicFunc)(void *);
583+
584+/* Callback function codes: save-content, save-info */
585+
586+/************************
587+ Xpad_periodic_init(): initializes this module
588+ Xpad_periodic_close(): frees resources of this module
589+************************/
590+gboolean Xpad_periodic_init(void);
591+void Xpad_periodic_close(void);
592+
593+/************************
594+ Xpad_periodic_set_callback():
595+ Sets up a callback function for a signal name.
596+ The signal names are "save-info" and "save-content"
597+************************/
598+gboolean Xpad_periodic_set_callback (const char *, XpadPeriodicFunc);
599+
600+/************************
601+ Xpad_periodic_save_content_delayed:
602+ Xpad_periodic_save_info_delayed:
603+ These functions prepare either the pad's content
604+ or info to be saved later.
605+************************/
606+void Xpad_periodic_save_content_delayed (void * xpad_pad);
607+void Xpad_periodic_save_info_delayed (void * xpad_pad);
608+void Xpad_periodic_signal (const char * cbname, void * xpad_pad);
609+
610+void Xpad_periodic_test (); /* aborts program */
611+void Xpad_periodic_error_exit (const char *, ...); /* ditto */
612+
613+#endif /* XPAD_PERIODIC_H */
614+
615+/************************
616+************************/
617+/* vim: set ts=4 sw=4 :vim */
618
619=== modified file 'src/xpad-tray.c'
620--- src/xpad-tray.c 2012-08-15 13:30:31 +0000
621+++ src/xpad-tray.c 2013-10-09 14:52:00 +0000
622@@ -188,7 +188,7 @@
623 gtk_widget_show (item);
624
625 item = gtk_image_menu_item_new_from_stock (GTK_STOCK_QUIT, NULL);
626- g_signal_connect (item, "activate", G_CALLBACK (gtk_main_quit), NULL);
627+ g_signal_connect (item, "activate", G_CALLBACK (xpad_app_quit), NULL);
628 gtk_container_add (GTK_CONTAINER (menu), item);
629 gtk_widget_show (item);
630

Subscribers

People subscribed via source and target branches