diff --git a/src/keyfile.c b/src/keyfile.c
index 7b29df7..e6d1273 100644
--- a/src/keyfile.c
+++ b/src/keyfile.c
@@ -253,7 +253,7 @@ static void save_recent_files(GKeyFile *config, GQueue *queue, gchar const *key)
 }
 
 
-static gchar *get_session_file_string(GeanyDocument *doc)
+static gchar *get_session_file_string(GeanyDocument *doc, gboolean relative)
 {
 	gchar *fname;
 	gchar *locale_filename;
@@ -263,6 +263,26 @@ static gchar *get_session_file_string(GeanyDocument *doc)
 		ft = filetypes[GEANY_FILETYPES_NONE];
 
 	locale_filename = utils_get_locale_from_utf8(doc->file_name);
+	if (app->project && relative)
+	{
+		gchar *project_dir, *file_dir, *tmp;
+
+		project_dir = g_path_get_dirname(app->project->file_name);
+		file_dir = g_path_get_dirname(locale_filename);
+		tmp = utils_relpath(project_dir, file_dir);
+		if (tmp)
+		{
+			gchar *basename;
+
+			basename = g_path_get_basename(locale_filename);
+			setptr(locale_filename, g_build_filename(tmp, basename, NULL));
+			g_free(basename);
+		}
+		g_free(project_dir);
+		g_free(file_dir);
+		g_free(tmp);
+	}
+
 	/* If the filename contains any ';' (semi-colons) we need to escape them otherwise
 	 * g_key_file_get_string_list() would fail reading them, so we replace them before
 	 * writing with usual colons which must never appear in a filename and replace them
@@ -285,7 +305,7 @@ static gchar *get_session_file_string(GeanyDocument *doc)
 }
 
 
-void configuration_save_session_files(GKeyFile *config)
+void configuration_save_session_files(GKeyFile *config, gboolean relative)
 {
 	gint npage;
 	gchar *tmp;
@@ -306,7 +326,7 @@ void configuration_save_session_files(GKeyFile *config)
 			gchar *fname;
 
 			g_snprintf(entry, sizeof(entry), "FILE_NAME_%d", j);
-			fname = get_session_file_string(doc);
+			fname = get_session_file_string(doc, relative);
 			g_key_file_set_string(config, "files", entry, fname);
 			g_free(fname);
 			j++;
@@ -551,7 +571,7 @@ void configuration_save(void)
 	save_recent_files(config, ui_prefs.recent_projects_queue, "recent_projects");
 
 	if (cl_options.load_session)
-		configuration_save_session_files(config);
+		configuration_save_session_files(config, FALSE);
 
 	/* write the file */
 	data = g_key_file_to_data(config, NULL, NULL);
@@ -901,7 +921,7 @@ void configuration_save_default_session(void)
 	g_key_file_load_from_file(config, configfile, G_KEY_FILE_NONE, NULL);
 
 	if (cl_options.load_session)
-		configuration_save_session_files(config);
+		configuration_save_session_files(config, FALSE);
 
 	/* write the file */
 	data = g_key_file_to_data(config, NULL, NULL);
@@ -981,6 +1001,15 @@ static gboolean open_session_file(gchar **tmp, guint len)
 	/* replace ':' back with ';' (see get_session_file_string for details) */
 	g_strdelimit((gchar*) utils_path_skip_root(locale_filename), ":", ';');
 
+	if (!g_path_is_absolute(locale_filename) && app->project)
+	{
+		gchar *project_dir;
+
+		project_dir = g_path_get_dirname(app->project->file_name);
+		setptr(locale_filename, g_build_filename(project_dir, locale_filename, NULL));
+		g_free(project_dir);
+	}
+
 	if (len > 8)
 		line_breaking = atoi(tmp[8]);
 
diff --git a/src/keyfile.h b/src/keyfile.h
index 3a8da08..d7fe33b 100644
--- a/src/keyfile.h
+++ b/src/keyfile.h
@@ -49,7 +49,7 @@ void configuration_save_default_session(void);
 
 void configuration_load_session_files(GKeyFile *config, gboolean read_recent_files);
 
-void configuration_save_session_files(GKeyFile *config);
+void configuration_save_session_files(GKeyFile *config, gboolean relative);
 
 /* set some settings which are already read from the config file, but need other things, like the
  * realisation of the main window */
diff --git a/src/project.c b/src/project.c
index 11f9ca2..b9f865e 100644
--- a/src/project.c
+++ b/src/project.c
@@ -1014,6 +1014,7 @@ static gboolean load_config(const gchar *filename)
 {
 	GKeyFile *config;
 	GeanyProject *p;
+	gchar *tmp;
 
 	/* there should not be an open project */
 	g_return_val_if_fail(app->project == NULL && filename != NULL, FALSE);
@@ -1032,7 +1033,18 @@ static gboolean load_config(const gchar *filename)
 	p->name = utils_get_setting_string(config, "project", "name", GEANY_STRING_UNTITLED);
 	p->description = utils_get_setting_string(config, "project", "description", "");
 	p->file_name = utils_get_utf8_from_locale(filename);
-	p->base_path = utils_get_setting_string(config, "project", "base_path", "");
+
+	tmp = utils_get_setting_string(config, "project", "base_path", "");
+	if (!g_path_is_absolute(tmp))
+	{
+		gchar *project_dir;
+
+		project_dir = g_path_get_dirname(p->file_name);
+		setptr(tmp, g_build_filename(project_dir, tmp, NULL));
+		utils_tidy_path(tmp);
+		g_free(project_dir);
+	}
+	p->base_path = tmp;
 	p->file_patterns = g_key_file_get_string_list(config, "project", "file_patterns", NULL, NULL);
 
 	p->long_line_behaviour = utils_get_setting_integer(config, "long line marker",
@@ -1079,6 +1091,7 @@ static gboolean write_config(gboolean emit_signal)
 	GKeyFile *config;
 	gchar *filename;
 	gchar *data;
+	gchar *tmp, *project_dir;
 	gboolean ret = FALSE;
 
 	g_return_val_if_fail(app->project != NULL, FALSE);
@@ -1093,7 +1106,14 @@ static gboolean write_config(gboolean emit_signal)
 	stash_group_save_to_key_file(indent_group, config);
 
 	g_key_file_set_string(config, "project", "name", p->name);
-	g_key_file_set_string(config, "project", "base_path", p->base_path);
+
+	project_dir = g_path_get_dirname(p->file_name);
+	tmp = utils_relpath(project_dir, p->base_path);
+	if (!tmp)
+		tmp = g_strdup(p->base_path);
+	g_key_file_set_string(config, "project", "base_path", tmp);
+	g_free(tmp);
+	g_free(project_dir);
 
 	if (p->description)
 		g_key_file_set_string(config, "project", "description", p->description);
@@ -1106,7 +1126,7 @@ static gboolean write_config(gboolean emit_signal)
 
 	/* store the session files into the project too */
 	if (project_prefs.project_session)
-		configuration_save_session_files(config);
+		configuration_save_session_files(config, TRUE);
 	build_save_menu(config, (gpointer)p, GEANY_BCS_PROJ);
 	if (emit_signal)
 	{
