mirror of
https://github.com/Cairo-Dock/cairo-dock-core.git
synced 2026-04-21 02:45:27 +02:00
Merge pull request #230 from dkondor/dbus_own_name
DBus: make Cairo-Dock single instance by default
This commit is contained in:
@@ -74,6 +74,7 @@
|
||||
#include "cairo-dock-packages.h"
|
||||
#include "cairo-dock-utils.h" // cairo_dock_launch_command
|
||||
#include "cairo-dock-core.h"
|
||||
#include "cairo-dock-dbus-priv.h" // cairo_dock_dbus_own_name
|
||||
|
||||
#include "cairo-dock-gui-manager.h"
|
||||
#include "cairo-dock-gui-backend.h"
|
||||
@@ -366,7 +367,9 @@ int main (int argc, char** argv)
|
||||
textdomain (CAIRO_DOCK_GETTEXT_PACKAGE);
|
||||
|
||||
//\___________________ get app's options.
|
||||
gboolean bSafeMode = FALSE, bMaintenance = FALSE, bNoSticky = FALSE, bCappuccino = FALSE, bPrintVersion = FALSE, bTesting = FALSE, bForceOpenGL = FALSE, bToggleIndirectRendering = FALSE, bKeepAbove = FALSE, bForceColors = FALSE, bAskBackend = FALSE, bTransparencyWorkaround = FALSE;
|
||||
gboolean bSafeMode = FALSE, bMaintenance = FALSE, bNoSticky = FALSE, bCappuccino = FALSE, bPrintVersion = FALSE,
|
||||
bTesting = FALSE, bForceOpenGL = FALSE, bToggleIndirectRendering = FALSE, bKeepAbove = FALSE, bForceColors = FALSE,
|
||||
bAskBackend = FALSE, bTransparencyWorkaround = FALSE, bAllowMultiInstance = FALSE, bNoDBusName = FALSE;
|
||||
gchar *cEnvironment = NULL, *cUserDefinedDataDir = NULL, *cVerbosity = 0, *cUserDefinedModuleDir = NULL, *cExcludeModule = NULL, *cThemeServerAdress = NULL;
|
||||
int iDelay = 0;
|
||||
GOptionEntry pOptionsTable[] =
|
||||
@@ -445,6 +448,12 @@ int main (int argc, char** argv)
|
||||
{"x11", 'X', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
|
||||
&g_bForceX11,
|
||||
_("Force using the X11 backend (disable any Wayland functionality)."), NULL},
|
||||
{"allow-multi-instance", 'I', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
|
||||
&bAllowMultiInstance,
|
||||
_("Allow multiple instances of Cairo-Dock to run."), NULL},
|
||||
{"no-dbus-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
|
||||
&bNoDBusName,
|
||||
_("Do not try to own the \"org.cairodock.CairoDock\" DBus name (DBus interface will be unavailable)."), NULL},
|
||||
{"egl", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE,
|
||||
&g_bX11UseEgl,
|
||||
_("Use EGL on X11."), NULL},
|
||||
@@ -529,6 +538,18 @@ int main (int argc, char** argv)
|
||||
g_free (cEnvironment);
|
||||
}
|
||||
|
||||
//\___________________ try to own our DBus name
|
||||
if (!bNoDBusName && !cairo_dock_dbus_own_name ())
|
||||
{
|
||||
if (!cairo_dock_dbus_is_enabled ())
|
||||
cd_warning ("DBus is unavailable, functions to communicate with apps and system components will not work!");
|
||||
else if (!bAllowMultiInstance)
|
||||
{
|
||||
//!! TODO: check if another instance is really running and responsive? (e.g. with a Ping-like call)
|
||||
cd_error ("Cairo-Dock is already running, not starting another instance (use the \"-I\" command line option to override).");
|
||||
}
|
||||
}
|
||||
|
||||
//\___________________ get global config.
|
||||
gboolean bFirstLaunch = FALSE;
|
||||
gchar *cRootDataDirPath;
|
||||
|
||||
@@ -55,7 +55,7 @@ SET(core_lib_SRCS
|
||||
cairo-dock-gui-manager.c cairo-dock-gui-manager.h
|
||||
cairo-dock-gui-factory.c cairo-dock-gui-factory.h
|
||||
cairo-dock-keybinder.c cairo-dock-keybinder.h
|
||||
cairo-dock-dbus.c cairo-dock-dbus.h
|
||||
cairo-dock-dbus.c cairo-dock-dbus.h cairo-dock-dbus-priv.h
|
||||
cairo-dock-keyfile-utilities.c cairo-dock-keyfile-utilities.h
|
||||
cairo-dock-packages.c cairo-dock-packages.h
|
||||
cairo-dock-particle-system.c cairo-dock-particle-system.h
|
||||
|
||||
36
src/gldit/cairo-dock-dbus-priv.h
Normal file
36
src/gldit/cairo-dock-dbus-priv.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* This file is a part of the Cairo-Dock project
|
||||
*
|
||||
* Copyright : (C) see the 'copyright' file.
|
||||
* E-mail : see the 'copyright' file.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __CAIRO_DOCK_DBUS_PRIV__
|
||||
#define __CAIRO_DOCK_DBUS_PRIV__
|
||||
|
||||
#include "cairo-dock-dbus.h"
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/** Try to own our DBus name (org.cairodock.CairoDock). This is a synchronous
|
||||
* function that will block until the name is acquired or rejected. It should
|
||||
* be only called during initialization as it will iterate the default context.
|
||||
*@return TRUE if the name has been acquired
|
||||
*/
|
||||
gboolean cairo_dock_dbus_own_name (void);
|
||||
|
||||
G_END_DECLS
|
||||
#endif
|
||||
|
||||
@@ -21,7 +21,68 @@
|
||||
#include <glib.h>
|
||||
|
||||
#include "cairo-dock-log.h"
|
||||
#include "cairo-dock-dbus.h"
|
||||
#include "cairo-dock-dbus-priv.h"
|
||||
|
||||
/***********************************************************************
|
||||
* New interface */
|
||||
|
||||
static GDBusConnection *s_pMainConnection = NULL;
|
||||
static const gchar *s_cBusName = "org.cairodock.CairoDock";
|
||||
static gboolean s_bNameOwned = FALSE;
|
||||
|
||||
|
||||
gboolean cairo_dock_dbus_is_enabled (void)
|
||||
{
|
||||
return (s_pMainConnection != NULL);
|
||||
}
|
||||
|
||||
GDBusConnection *cairo_dock_dbus_get_session_bus (void)
|
||||
{
|
||||
return s_pMainConnection;
|
||||
}
|
||||
|
||||
const gchar *cairo_dock_dbus_get_owned_name (void)
|
||||
{
|
||||
return s_bNameOwned ? s_cBusName : NULL;
|
||||
}
|
||||
|
||||
static void _on_bus_acquired (GDBusConnection *pConn, G_GNUC_UNUSED const gchar* cName, G_GNUC_UNUSED gpointer ptr)
|
||||
{
|
||||
s_pMainConnection = pConn;
|
||||
}
|
||||
|
||||
|
||||
gboolean s_bNameAcquiredOrLost = FALSE;
|
||||
|
||||
static void _on_name_acquired (G_GNUC_UNUSED GDBusConnection* pConn, G_GNUC_UNUSED const gchar* cName, G_GNUC_UNUSED gpointer data)
|
||||
{
|
||||
s_bNameOwned = TRUE;
|
||||
s_bNameAcquiredOrLost = TRUE;
|
||||
}
|
||||
|
||||
static void _on_name_lost (G_GNUC_UNUSED GDBusConnection* pConn, G_GNUC_UNUSED const gchar* cName, G_GNUC_UNUSED gpointer data)
|
||||
{
|
||||
s_bNameOwned = FALSE;
|
||||
s_bNameAcquiredOrLost = TRUE;
|
||||
}
|
||||
|
||||
gboolean cairo_dock_dbus_own_name (void)
|
||||
{
|
||||
//\____________ Register the service name (the service name is registerd once by the first gldi instance).
|
||||
g_bus_own_name (G_BUS_TYPE_SESSION, s_cBusName, G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE, _on_bus_acquired, // bus acquired handler
|
||||
_on_name_acquired, _on_name_lost, NULL, NULL);
|
||||
|
||||
// Wait until we have acquired the bus. This is necessary as we want to know whether we succeeded.
|
||||
GMainContext *pContext = g_main_context_default ();
|
||||
do g_main_context_iteration (pContext, TRUE);
|
||||
while (!s_bNameAcquiredOrLost);
|
||||
|
||||
return s_bNameOwned;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Deprecated interface -- to be removed. */
|
||||
|
||||
static DBusGConnection *s_pSessionConnexion = NULL;
|
||||
static DBusGConnection *s_pSystemConnexion = NULL;
|
||||
@@ -101,12 +162,6 @@ gboolean cairo_dock_register_service_name (const gchar *cServiceName)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
gboolean cairo_dock_dbus_is_enabled (void)
|
||||
{
|
||||
return (cairo_dock_get_session_connection () != NULL && cairo_dock_get_system_connection () != NULL);
|
||||
}
|
||||
|
||||
static void on_name_owner_changed (G_GNUC_UNUSED DBusGProxy *pProxy, const gchar *cName, G_GNUC_UNUSED const gchar *cPrevOwner, const gchar *cNewOwner, G_GNUC_UNUSED gpointer data)
|
||||
{
|
||||
//g_print ("%s (%s)\n", __func__, cName);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define __CAIRO_DOCK_DBUS__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <dbus/dbus-glib-bindings.h>
|
||||
G_BEGIN_DECLS
|
||||
@@ -32,6 +33,29 @@ G_BEGIN_DECLS
|
||||
*/
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* New interface */
|
||||
|
||||
|
||||
/** Say if the bus is available or not.
|
||||
*@return TRUE if the connection to the bus has been established.
|
||||
*/
|
||||
gboolean cairo_dock_dbus_is_enabled (void);
|
||||
|
||||
/** Get a connection to the session bus (if connected).
|
||||
*@return main DBusConnection to the session bus or NULL if unavailable
|
||||
*/
|
||||
GDBusConnection *cairo_dock_dbus_get_session_bus (void);
|
||||
|
||||
/** Get the DBus well-known name under which Cairo-Dock is registered
|
||||
* on the session bus. By default, it is "org.CairoDock.cairodock".
|
||||
*@return the DBus name registered or NULL if we do not own a DBus name
|
||||
*/
|
||||
const gchar *cairo_dock_dbus_get_owned_name (void);
|
||||
|
||||
|
||||
/** Deprecated interface -- to be removed. */
|
||||
|
||||
typedef void (*CairoDockDbusNameOwnerChangedFunc) (const gchar *cName, gboolean bOwned, gpointer data);
|
||||
|
||||
/** Get the connection to the 'session' Bus.
|
||||
@@ -50,10 +74,6 @@ DBusGProxy *cairo_dock_get_main_system_proxy (void);
|
||||
*/
|
||||
gboolean cairo_dock_register_service_name (const gchar *cServiceName);
|
||||
|
||||
/** Say if the bus is available or not.
|
||||
*@return TRUE if the connection to the bus has been established.
|
||||
*/
|
||||
gboolean cairo_dock_dbus_is_enabled (void);
|
||||
|
||||
void cairo_dock_watch_dbus_name_owner (const char *cName, CairoDockDbusNameOwnerChangedFunc pCallback, gpointer data);
|
||||
|
||||
|
||||
@@ -95,17 +95,16 @@ static void _read_module_config (GKeyFile *pKeyFile, GldiModuleInstance *pInstan
|
||||
|
||||
bFlushConfFileNeeded = pInterface->read_conf_file (pInstance, pKeyFile);
|
||||
}
|
||||
if (! bFlushConfFileNeeded)
|
||||
bFlushConfFileNeeded = cairo_dock_conf_file_needs_update (pKeyFile, pVisitCard->cModuleVersion);
|
||||
if (bFlushConfFileNeeded)
|
||||
{
|
||||
// if there were still missing values (the plug-in uses some setting not in its template)
|
||||
gchar *cTemplate = g_strdup_printf ("%s/%s", pVisitCard->cShareDataDir, pVisitCard->cConfFileName);
|
||||
cairo_dock_upgrade_conf_file_full (pInstance->cConfFilePath, pKeyFile, cTemplate, FALSE); // keep private keys.
|
||||
g_free (cTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
GKeyFile *gldi_module_instance_open_conf_file (GldiModuleInstance *pInstance, CairoDockMinimalAppletConfig *pMinimalConfig)
|
||||
static GKeyFile *_open_conf_file (GldiModuleInstance *pInstance, CairoDockMinimalAppletConfig *pMinimalConfig, gboolean bCheckUpdate)
|
||||
{
|
||||
g_return_val_if_fail (pInstance != NULL, NULL);
|
||||
//\____________________ we open its config file.
|
||||
@@ -117,6 +116,20 @@ GKeyFile *gldi_module_instance_open_conf_file (GldiModuleInstance *pInstance, Ca
|
||||
if (pKeyFile == NULL) // unreadable file.
|
||||
return NULL;
|
||||
|
||||
// check if we need to update the key file
|
||||
if (bCheckUpdate && cairo_dock_conf_file_needs_update (pKeyFile, pInstance->pModule->pVisitCard->cModuleVersion))
|
||||
{
|
||||
// update to the new version first, so that default values will be read already (no missing values in the next step)
|
||||
gchar *cTemplate = g_strdup_printf ("%s/%s", pInstance->pModule->pVisitCard->cShareDataDir, pInstance->pModule->pVisitCard->cConfFileName);
|
||||
cairo_dock_upgrade_conf_file_full (cInstanceConfFilePath, pKeyFile, cTemplate, FALSE); // keep private keys.
|
||||
g_free (cTemplate);
|
||||
|
||||
// re-read the updated file -- this is a bit wasteful, but this does not happen often
|
||||
g_key_file_free (pKeyFile);
|
||||
pKeyFile = cairo_dock_open_key_file (cInstanceConfFilePath);
|
||||
g_return_val_if_fail (pKeyFile, NULL); // something went wrong -- should not happen
|
||||
}
|
||||
|
||||
if (pInstance->pModule->pVisitCard->iContainerType == CAIRO_DOCK_MODULE_IS_PLUGIN) // This module doesn't have any icon (not an applet).
|
||||
{
|
||||
return pKeyFile;
|
||||
@@ -255,6 +268,11 @@ GKeyFile *gldi_module_instance_open_conf_file (GldiModuleInstance *pInstance, Ca
|
||||
return pKeyFile;
|
||||
}
|
||||
|
||||
GKeyFile *gldi_module_instance_open_conf_file (GldiModuleInstance *pInstance, CairoDockMinimalAppletConfig *pMinimalConfig)
|
||||
{
|
||||
return _open_conf_file (pInstance, pMinimalConfig, FALSE);
|
||||
}
|
||||
|
||||
void gldi_module_instance_free_generic_config (CairoDockMinimalAppletConfig *pMinimalConfig)
|
||||
{
|
||||
if (pMinimalConfig == NULL)
|
||||
@@ -407,7 +425,7 @@ static void init_object (GldiObject *obj, gpointer attr)
|
||||
|
||||
//\____________________ open the conf file.
|
||||
CairoDockMinimalAppletConfig *pMinimalConfig = g_new0 (CairoDockMinimalAppletConfig, 1);
|
||||
GKeyFile *pKeyFile = gldi_module_instance_open_conf_file (pInstance, pMinimalConfig);
|
||||
GKeyFile *pKeyFile = _open_conf_file (pInstance, pMinimalConfig, TRUE); // TRUE -> already apply any update from settings template
|
||||
if (pInstance->cConfFilePath != NULL && pKeyFile == NULL) // we have a conf file, but it was unreadable -> cancel
|
||||
{
|
||||
//!! TODO: pInstance will likely be leaked in this case !!
|
||||
|
||||
Reference in New Issue
Block a user