Le 07/10/2010 16:17, Nick Treleaven a écrit :
> On Wed, 29 Sep 2010 18:00:06 +0100
> Nick Treleaven <[email protected]> wrote:
>
>>>> 3) this is the most complicated but also the one that seems to have the
>>>> less flaws: still add workspace suffix, but when checking if there is a
>>>> running instance to which send the requests, ignore that workspace
>>>> information if the pre-workspace option is not checked. It needs to list
>>>> the available socket(s), and then select the one we want (probably the
>>>> first or the one closets to the current desktop), but it fixes flaws I
>>>> see in both methods 1) and 2).
>>>
>>> I prefer this solution, mainly because it doesn't have the problems the
>>> other two solutions have.
>>
>> In any case, the patch introduced a bug where 2nd instances still load
>> the session files. So I think we'll need to revert it until there's a
>> fix.
>
> I've now copied the code to branches/workspace-sockets and reverted the
> code in trunk. Hopefully we can fix the issues and merge back
> sometime.
Cool (for me :D), I'd also think it needs a little more incubation.
IMO the current design is a bit flawed since if the instance is moved to
another workspace, it still behaves as if on its original workspace.
Not sure how this could be fixed, but it needs to be fixed before
merging to trunk IMO.
I don't know what's possible to do, but I see some possibilities:
1) Detect workspace change, and then change socket name. This is not
really easy since it needs handling the case when there is already an
instance on this workspace.
2) When trying to open a file on a running instance, ask its workspace
before actually sending the commands. This needs to list existing
sockets and add a way to communicate the workspace through it. But then,
this would look like:
socket = None
for s in socket_list:
if s.workspace == current_workspace:
socket = s
break
if socket is not None:
socket.send_command(...)
else:
open_new_instance()
Note that the sockets no longer should be workspace-suffixed, since this
workspace ID would sometime be wrong. Better use a random/incrementing
suffix.
Perhaps a look at how GEdit handles this would provide some ideas?
> One idea besides having a pref for this is to have a command-line option
> to use the 'main' socket instead of the current workspace.
Why not, but it's not really convenient for those who use launchers:
they need to be modified. But it would fix the problem that the prefs
are currently loaded *after* socket checks.
BTW, I join the first patch I did to implement my 3rd proposal so if
anybody's interested, they can take a look. I run it since I wrote it (a
week ago), and seems to work fine -- apart the pref that is not loaded
at the time I use it.
Regards,
Colomban
Index: src/keyfile.c
===================================================================
--- src/keyfile.c (révision 5261)
+++ src/keyfile.c (copie de travail)
@@ -115,6 +115,8 @@
configuration_add_pref_group(group, TRUE);
stash_group_add_entry(group, &prefs.default_open_path,
"default_open_path", "", "startup_path_entry");
+ stash_group_add_boolean(group, &prefs.per_workspace_instances,
+ "per_workspace_instances", FALSE);
stash_group_add_toggle_button(group, &file_prefs.cmdline_new_files,
"cmdline_new_files", TRUE, "check_cmdline_new_files");
Index: src/prefs.h
===================================================================
--- src/prefs.h (révision 5261)
+++ src/prefs.h (copie de travail)
@@ -36,6 +36,7 @@
gboolean auto_focus;
gchar *default_open_path; /**< Default path to look for files when no other path is appropriate. */
gchar *custom_plugin_path;
+ gboolean per_workspace_instances;
}
GeanyPrefs;
Index: src/socket.c
===================================================================
--- src/socket.c (révision 5261)
+++ src/socket.c (copie de travail)
@@ -88,6 +88,7 @@
#include "utils.h"
#include "dialogs.h"
#include "encodings.h"
+#include "prefs.h"
@@ -108,6 +109,7 @@
static gint socket_fd_open_inet (gushort port);
static void socket_init_win32 (void);
#else
+static gchar *socket_get_candidate_unix (const gchar *path);
static gint socket_fd_connect_unix (const gchar *path);
static gint socket_fd_open_unix (const gchar *path);
#endif
@@ -285,9 +287,20 @@
*p = '_';
if (socket_info.file_name == NULL)
- socket_info.file_name = g_strdup_printf("%s%cgeany_socket_%s_%s_ws%d",
- app->configdir, G_DIR_SEPARATOR, hostname, display_name, workspace);
+ {
+ gchar *file_name;
+ file_name = g_strdup_printf("%s%cgeany_socket_%s_%s_ws%d",
+ app->configdir, G_DIR_SEPARATOR, hostname, display_name, workspace);
+ if (prefs.per_workspace_instances)
+ socket_info.file_name = file_name;
+ else
+ {
+ socket_info.file_name = socket_get_candidate_unix(file_name);
+ g_free(file_name);
+ }
+ }
+
g_free(display_name);
g_free(hostname);
@@ -355,6 +368,71 @@
#ifdef G_OS_UNIX
+/* gets how socket name @name is close to the searched name @search. smaller
+ * values means closer result. */
+static gint socket_candidate_level_unix(const gchar *search, const gchar *name)
+{
+ gint ret;
+
+ while (*search && (ret = *search - *name) == 0)
+ {
+ search ++;
+ name ++;
+ }
+
+ return ABS(ret);
+}
+
+
+/* finds out the better socket cantidate for socket path @path, and return it.
+ * if none is found, returns a copy of @path. */
+static gchar *socket_get_candidate_unix(const gchar *path)
+{
+ gchar *dirpath = g_path_get_dirname(path);
+ gchar *found = g_strdup(path);
+ GDir *dir;
+
+ dir = g_dir_open(dirpath, 0, NULL);
+ if (dir)
+ {
+ gchar *basepath = g_path_get_basename(path);
+ gint pertinance = G_MAXINT;
+ gchar *pattern;
+ gchar *p;
+ const gchar *name;
+
+ /* pattern is full socket name without workspace ID */
+ pattern = g_strdup(basepath);
+ p = utils_strrstr(pattern, "_ws");
+ if (p)
+ *(p + 3) = 0;
+
+ while ((name = g_dir_read_name(dir)) != NULL)
+ {
+ if (g_str_has_prefix(name, pattern))
+ {
+ gint name_pertinance;
+
+ name_pertinance = socket_candidate_level_unix(basepath, name);
+ if (name_pertinance < pertinance)
+ {
+ setptr(found, g_build_filename(dirpath, name, NULL));
+ pertinance = name_pertinance;
+ }
+ }
+ }
+
+ g_free(pattern);
+ g_free(basepath);
+
+ g_dir_close(dir);
+ }
+ g_free(dirpath);
+
+ return found;
+}
+
+
static gint socket_fd_connect_unix(const gchar *path)
{
gint sock;
Index: src/utils.c
===================================================================
--- src/utils.c (révision 5261)
+++ src/utils.c (copie de travail)
@@ -702,6 +702,30 @@
}
+/* strstr() but finds the last occurrence rather than the first one */
+gchar *utils_strrstr(const gchar *haystack, const gchar *needle)
+{
+ size_t haystack_len = strlen (haystack);
+ size_t needle_len = strlen (needle);
+ const gchar *found = NULL;
+
+ if (haystack_len >= needle_len)
+ {
+ size_t i;
+
+ for (i = 1 + haystack_len - needle_len; ! found && i > 0; i--)
+ {
+ const gchar *p = &haystack[i - 1];
+
+ if (p[0] == needle[0] && strncmp (p, needle, needle_len) == 0)
+ found = p;
+ }
+ }
+
+ return (gchar *)found;
+}
+
+
/**
* Retrieves a formatted date/time string from strftime().
* This function should be preferred to directly calling strftime() since this function
Index: src/utils.h
===================================================================
--- src/utils.h (révision 5261)
+++ src/utils.h (copie de travail)
@@ -159,6 +159,8 @@
gint utils_strpos(const gchar* haystack, const gchar *needle);
+gchar *utils_strrstr(const gchar *haystack, const gchar *needle);
+
gchar *utils_get_date_time(const gchar *format, time_t *time_to_use);
gchar *utils_get_initials(const gchar *name);
_______________________________________________
Geany-devel mailing list
[email protected]
http://lists.uvena.de/cgi-bin/mailman/listinfo/geany-devel