diff --git a/CMakeLists.txt b/CMakeLists.txt index 43e0b22e8..72b3a6fbd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ include ("${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/GNUInstallDirs.cmake") ########### project ############### project ("cairo-dock") -set (VERSION "3.5.0") # no dash, only numbers, dots and maybe alpha/beta/rc, e.g.: 3.3.1 or 3.3.99.alpha1 +set (VERSION "3.5.1") # no dash, only numbers, dots and maybe alpha/beta/rc, e.g.: 3.3.1 or 3.3.99.alpha1 add_definitions (-std=c99 -Wall -Wextra -Werror-implicit-function-declaration) # -Wextra -Wwrite-strings -Wuninitialized -Werror-implicit-function-declaration -Wstrict-prototypes -Wreturn-type -Wparentheses -Warray-bounds) if (NOT DEFINED CMAKE_BUILD_TYPE) diff --git a/Help/src/applet-tips-dialog.c b/Help/src/applet-tips-dialog.c index ea3fa4943..f3b723e1b 100644 --- a/Help/src/applet-tips-dialog.c +++ b/Help/src/applet-tips-dialog.c @@ -40,7 +40,7 @@ static void _cairo_dock_get_next_tip (CDTipsData *pTips) { pTips->iNumTipKey ++; // skip the current expander to go to the current label, which will be skipped in the first iteration. const gchar *cGroupName = pTips->pGroupList[pTips->iNumTipGroup]; - gboolean bOk; + gboolean bOk = FALSE; do { pTips->iNumTipKey ++; @@ -77,8 +77,13 @@ static void _cairo_dock_get_next_tip (CDTipsData *pTips) // check if the key is an expander widget. const gchar *cKeyName = pTips->pKeyList[pTips->iNumTipKey]; gchar *cKeyComment = g_key_file_get_comment (pTips->pKeyFile, cGroupName, cKeyName, NULL); - bOk = (cKeyComment && *cKeyComment == CAIRO_DOCK_WIDGET_EXPANDER); // whether it's an expander. - g_free (cKeyComment); + if (cKeyComment) + { + gchar *tmp = cKeyComment; + while (*tmp == '\t' || *tmp == '\n' || *tmp == ' ') ++tmp; + bOk = (*tmp == CAIRO_DOCK_WIDGET_EXPANDER); // whether it's an expander. + g_free (cKeyComment); + } } while (!bOk); } @@ -87,7 +92,7 @@ static void _cairo_dock_get_previous_tip (CDTipsData *pTips) pTips->iNumTipKey --; const gchar *cGroupName = pTips->pGroupList[pTips->iNumTipGroup]; - gboolean bOk; + gboolean bOk = FALSE; do { pTips->iNumTipKey --; @@ -125,7 +130,13 @@ static void _cairo_dock_get_previous_tip (CDTipsData *pTips) // check if the key is an expander widget. const gchar *cKeyName = pTips->pKeyList[pTips->iNumTipKey]; gchar *cKeyComment = g_key_file_get_comment (pTips->pKeyFile, cGroupName, cKeyName, NULL); - bOk = (cKeyComment && *cKeyComment == CAIRO_DOCK_WIDGET_EXPANDER); // whether it's an expander. + if (cKeyComment) + { + gchar *tmp = cKeyComment; + while (*tmp == '\t' || *tmp == '\n' || *tmp == ' ') ++tmp; + bOk = (*tmp == CAIRO_DOCK_WIDGET_EXPANDER); // whether it's an expander. + g_free (cKeyComment); + } } while (!bOk); } @@ -276,10 +287,6 @@ void cairo_dock_show_tips (void) pTips->iNumTipGroup = iNumTipGroup; pTips->iNumTipKey = iNumTipKey; - // update to the next tip. - if (myData.iLastTipGroup >= 0 && myData.iLastTipKey >= 0) // a previous tip exist => take the next one; - _cairo_dock_get_next_tip (pTips); - // build a list of the available groups. GtkWidget *pInteractiveWidget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3); GtkWidget *pComboBox = gtk_combo_box_text_new (); @@ -290,6 +297,11 @@ void cairo_dock_show_tips (void) } gtk_combo_box_set_active (GTK_COMBO_BOX (pComboBox), pTips->iNumTipGroup); pTips->pCategoryCombo = pComboBox; + + // update to the next tip. + if (myData.iLastTipGroup >= 0 && myData.iLastTipKey >= 0) // a previous tip exist => take the next one; + _cairo_dock_get_next_tip (pTips); + static gpointer data_combo[2]; data_combo[0] = pTips; // the 2nd data is the dialog, we'll set it after we make it. g_signal_connect (G_OBJECT (pComboBox), "changed", G_CALLBACK(_on_tips_category_changed), data_combo); diff --git a/data/desktop-manager/gnome-session-3.36/gnome-session-x11@cairo-dock-compiz.target b/data/desktop-manager/gnome-session-3.36/gnome-session-x11@cairo-dock-compiz.target index 60fc23a36..a26606b73 100644 --- a/data/desktop-manager/gnome-session-3.36/gnome-session-x11@cairo-dock-compiz.target +++ b/data/desktop-manager/gnome-session-3.36/gnome-session-x11@cairo-dock-compiz.target @@ -20,15 +20,4 @@ After=gnome-flashback.target BindsTo=gnome-session.target After=gnome-session.target -Requires=indicators-pre.target - -# here we list the indicators that we want to load -Wants=indicator-application.service -Wants=indicator-bluetooth.service -Wants=indicator-datetime.service -Wants=indicator-keyboard.service -Wants=indicator-messages.service -Wants=indicator-power.service -Wants=indicator-printers.service -Wants=indicator-session.service -Wants=indicator-sound.service +Wants=ayatana-indicators.target diff --git a/data/desktop-manager/gnome-session-3.36/gnome-session-x11@cairo-dock-metacity.target b/data/desktop-manager/gnome-session-3.36/gnome-session-x11@cairo-dock-metacity.target index 60fc23a36..a26606b73 100644 --- a/data/desktop-manager/gnome-session-3.36/gnome-session-x11@cairo-dock-metacity.target +++ b/data/desktop-manager/gnome-session-3.36/gnome-session-x11@cairo-dock-metacity.target @@ -20,15 +20,4 @@ After=gnome-flashback.target BindsTo=gnome-session.target After=gnome-session.target -Requires=indicators-pre.target - -# here we list the indicators that we want to load -Wants=indicator-application.service -Wants=indicator-bluetooth.service -Wants=indicator-datetime.service -Wants=indicator-keyboard.service -Wants=indicator-messages.service -Wants=indicator-power.service -Wants=indicator-printers.service -Wants=indicator-session.service -Wants=indicator-sound.service +Wants=ayatana-indicators.target diff --git a/data/themes/default-theme-panel/launchers/01gcalctool.desktop b/data/themes/default-theme-panel/launchers/01gnome-calculator.desktop similarity index 94% rename from data/themes/default-theme-panel/launchers/01gcalctool.desktop rename to data/themes/default-theme-panel/launchers/01gnome-calculator.desktop index 406aeca38..c800680d6 100644 --- a/data/themes/default-theme-panel/launchers/01gcalctool.desktop +++ b/data/themes/default-theme-panel/launchers/01gnome-calculator.desktop @@ -47,4 +47,4 @@ Order=6.25 Icon Type=0 Type=Application -Origin=/usr/share/applications/gcalctool.desktop;kcalc.desktop;galculator.desktop +Origin=/usr/share/applications/gnome-calculator.desktop;kcalc.desktop diff --git a/data/themes/default-theme-panel/launchers/CMakeLists.txt b/data/themes/default-theme-panel/launchers/CMakeLists.txt index 2025d9d6d..4f31229a8 100644 --- a/data/themes/default-theme-panel/launchers/CMakeLists.txt +++ b/data/themes/default-theme-panel/launchers/CMakeLists.txt @@ -4,7 +4,7 @@ install(FILES 01container.desktop 01firefox.desktop - 01gcalctool.desktop + 01gnome-calculator.desktop 01libreoffice-calc.desktop 01libreoffice-impress.desktop 01libreoffice-writer.desktop diff --git a/data/themes/default-theme/launchers/01gcalctool.desktop b/data/themes/default-theme/launchers/01gnome-calculator.desktop similarity index 94% rename from data/themes/default-theme/launchers/01gcalctool.desktop rename to data/themes/default-theme/launchers/01gnome-calculator.desktop index 1ab6a996a..d7b7398fe 100644 --- a/data/themes/default-theme/launchers/01gcalctool.desktop +++ b/data/themes/default-theme/launchers/01gnome-calculator.desktop @@ -47,4 +47,4 @@ Order=4 Icon Type=0 Type=Application -Origin=/usr/share/applications/gcalctool.desktop;kcalc.desktop;galculator.desktop +Origin=/usr/share/applications/gnome-calculator.desktop;kcalc.desktop diff --git a/data/themes/default-theme/launchers/CMakeLists.txt b/data/themes/default-theme/launchers/CMakeLists.txt index b9566d4ba..5da53b500 100644 --- a/data/themes/default-theme/launchers/CMakeLists.txt +++ b/data/themes/default-theme/launchers/CMakeLists.txt @@ -3,7 +3,7 @@ install(FILES 01firefox.desktop - 01gcalctool.desktop + 01gnome-calculator.desktop 01gimp.desktop 01gnome-terminal.desktop 01ooo-writer.desktop diff --git a/src/cairo-dock-user-menu.c b/src/cairo-dock-user-menu.c index aa93cb900..5ed8fcd82 100644 --- a/src/cairo-dock-user-menu.c +++ b/src/cairo-dock-user-menu.c @@ -926,7 +926,7 @@ static void _cairo_dock_set_custom_appli_icon (G_GNUC_UNUSED GtkMenuItem *pMenuI } // apres la boucle, i = nbre d'elements, j = l'element qui a ete enleve. if (j != -1) // un element a ete enleve. { - cd_warning ("The class '%s' was explicitely set up to use the X icon, we'll change this behavior automatically.", icon->cClass); + cd_warning ("The class '%s' was explicitly set up to use the X icon, we'll change this behavior automatically.", icon->cClass); if (j < i - 1) // ce n'est pas le dernier { pExceptions[j] = pExceptions[i-1]; diff --git a/src/gldit/cairo-dock-applications-manager.c b/src/gldit/cairo-dock-applications-manager.c index 24efde009..b7992a6ae 100644 --- a/src/gldit/cairo-dock-applications-manager.c +++ b/src/gldit/cairo-dock-applications-manager.c @@ -989,6 +989,7 @@ static void init_object (GldiObject *obj, gpointer attr) icon->cName = g_strdup (actor->cName ? actor->cName : actor->cClass); icon->cClass = g_strdup (actor->cClass); // we'll register the class during the loading of the icon, since it can take some time, and we don't really need the class params right now. + icon->cWmClass = g_strdup (actor->cWmClass); icon->iface.load_image = _load_appli; icon->iface.action_on_drag_hover = _show_appli_for_drop; diff --git a/src/gldit/cairo-dock-class-icon-manager.c b/src/gldit/cairo-dock-class-icon-manager.c index e94498392..a2a5bd7f6 100644 --- a/src/gldit/cairo-dock-class-icon-manager.c +++ b/src/gldit/cairo-dock-class-icon-manager.c @@ -101,7 +101,8 @@ static void init_object (GldiObject *obj, gpointer attr) pIcon->iface.load_image = _load_image; pIcon->iGroup = pSameClassIcon->iGroup; - pIcon->cName = g_strdup (pSameClassIcon->cClass); + const gchar *cClassName = cairo_dock_get_class_name(pSameClassIcon->cClass); + pIcon->cName = g_strdup (cClassName ? cClassName : pSameClassIcon->cClass); pIcon->cCommand = g_strdup (pSameClassIcon->cCommand); pIcon->pMimeTypes = g_strdupv (pSameClassIcon->pMimeTypes); pIcon->cClass = g_strdup (pSameClassIcon->cClass); diff --git a/src/gldit/cairo-dock-class-manager.c b/src/gldit/cairo-dock-class-manager.c index e9aad7f63..2f9dccb41 100644 --- a/src/gldit/cairo-dock-class-manager.c +++ b/src/gldit/cairo-dock-class-manager.c @@ -1595,6 +1595,25 @@ const CairoDockImageBuffer *cairo_dock_get_class_image_buffer (const gchar *cCla } +static gboolean _check_desktop_file_exists(GString *sDesktopFilePath, const gchar *cFileName, const char *prefix) +{ + // TODO: use XDG_DATA_DIRS instead of hard-coded values! + if (prefix) g_string_printf (sDesktopFilePath, "/usr/share/applications/%s%s", prefix, cFileName); + else g_string_printf (sDesktopFilePath, "/usr/share/applications/%s", cFileName); + if (g_file_test (sDesktopFilePath->str, G_FILE_TEST_EXISTS)) return TRUE; + + if(prefix) g_string_printf (sDesktopFilePath, "/usr/local/share/applications/%s%s", prefix, cFileName); + else g_string_printf (sDesktopFilePath, "/usr/local/share/applications/%s", cFileName); + if (g_file_test (sDesktopFilePath->str, G_FILE_TEST_EXISTS)) return TRUE; + + if(prefix) g_string_printf (sDesktopFilePath, "%s/.local/share/applications/%s%s", g_getenv ("HOME"), prefix, cFileName); + else g_string_printf (sDesktopFilePath, "%s/.local/share/applications/%s", g_getenv ("HOME"), cFileName); + if (g_file_test (sDesktopFilePath->str, G_FILE_TEST_EXISTS)) return TRUE; + + return FALSE; +} + + static gchar *_search_desktop_file (const gchar *cDesktopFile) // file, path or even class { if (cDesktopFile == NULL) @@ -1611,29 +1630,38 @@ static gchar *_search_desktop_file (const gchar *cDesktopFile) // file, path or cDesktopFileName = g_strdup_printf ("%s.desktop", cDesktopFile); const gchar *cFileName = (cDesktopFileName ? cDesktopFileName : cDesktopFile); - gboolean bFound = TRUE; + gboolean bFound; GString *sDesktopFilePath = g_string_new (""); - g_string_printf (sDesktopFilePath, "/usr/share/applications/%s", cFileName); - if (! g_file_test (sDesktopFilePath->str, G_FILE_TEST_EXISTS)) + gchar *cFileNameLower = NULL; + + bFound = _check_desktop_file_exists (sDesktopFilePath, cFileName, NULL); + + if (! bFound) { - g_string_printf (sDesktopFilePath, "/usr/share/applications/%c%s", g_ascii_toupper (*cFileName), cFileName+1); // handle stupid cases like Thunar.desktop - if (! g_file_test (sDesktopFilePath->str, G_FILE_TEST_EXISTS)) + cFileNameLower = g_ascii_strdown (cFileName, -1); + bFound = _check_desktop_file_exists (sDesktopFilePath, cFileNameLower, NULL); + } + if (! bFound) + { + const char *prefices[] = {"org.gnome.", "org.kde.", "org.freedesktop.", "xfce4/", "kde4/", NULL}; + int i, j; + for (i = 0; i < 3; i++) { - g_string_printf (sDesktopFilePath, "/usr/share/applications/xfce4/%s", cFileName); - if (! g_file_test (sDesktopFilePath->str, G_FILE_TEST_EXISTS)) + /* note: third iteration is to handle very stupid cases such as + * org.gnome.Evince.desktop with app-id == "evince" (happens for + * version 42.3 that is on Ubuntu 22.04) */ + if (i == 2) cFileNameLower[0] = g_ascii_toupper (cFileNameLower[0]); + const gchar *tmp = i ? cFileNameLower : cFileName; + for (j = 0; prefices[j]; j++) { - g_string_printf (sDesktopFilePath, "/usr/share/applications/kde4/%s", cFileName); - if (! g_file_test (sDesktopFilePath->str, G_FILE_TEST_EXISTS)) - { - g_string_printf (sDesktopFilePath, "%s/.local/share/applications/%s", g_getenv ("HOME"), cFileName); - if (! g_file_test (sDesktopFilePath->str, G_FILE_TEST_EXISTS)) - { - bFound = FALSE; - } - } + bFound = _check_desktop_file_exists (sDesktopFilePath, tmp, prefices[j]); + if (bFound) break; } + if (bFound) break; } } + + g_free (cFileNameLower); g_free (cDesktopFileName); gchar *cResult; @@ -1772,13 +1800,15 @@ gchar *cairo_dock_guess_class (const gchar *cCommand, const gchar *cStartupWMCla g_free (cDefaultClass); } else - { cResult = g_ascii_strdown (cStartupWMClass, -1); - gchar *str = strchr (cResult, '.'); // we remove all .xxx otherwise we can't detect the lack of extension when looking for an icon (openoffice.org) or it's a problem when looking for an icon (jbrout.py). - if (str != NULL) - *str = '\0'; + + if (cResult) + { + // remove some suffices that can be problematic: .exe, .py (note: cResult is already lowercase here) + if (g_str_has_suffix (cResult, ".exe")) cResult[strlen (cResult) - 4] = 0; + else if (g_str_has_suffix (cResult, ".py")) cResult[strlen (cResult) - 3] = 0; + cairo_dock_remove_version_from_string (cResult); } - cairo_dock_remove_version_from_string (cResult); cd_debug (" -> '%s'", cResult); return cResult; @@ -1865,6 +1895,8 @@ gchar *cairo_dock_register_class_full (const gchar *cDesktopFile, const gchar *c //\__________________ search the desktop file's path. gchar *cDesktopFilePath = _search_desktop_file (cDesktopFile?cDesktopFile:cClass); + if (cDesktopFilePath == NULL && cWmClass != NULL) + cDesktopFilePath = _search_desktop_file (cWmClass); if (cDesktopFilePath == NULL) // couldn't find the .desktop { if (cClass != NULL) // make a class anyway to store the few info we have. diff --git a/src/implementations/cairo-dock-X-manager.c b/src/implementations/cairo-dock-X-manager.c index 373140f9c..dfe7adeb6 100644 --- a/src/implementations/cairo-dock-X-manager.c +++ b/src/implementations/cairo-dock-X-manager.c @@ -581,7 +581,7 @@ static gboolean _cairo_dock_unstack_Xevents (G_GNUC_UNUSED gpointer data) if (xactor->bIgnored) // was ignored, simply recreate it { // remove it from the table, so that the XEvent loop detects it again - g_hash_table_remove (s_hXWindowTable, &Xid); // remove it explicitely, because the 'unref' might not free it + g_hash_table_remove (s_hXWindowTable, &Xid); // remove it explicitly, because the 'unref' might not free it xactor->iLastCheckTime = -1; _delete_actor (xactor); // unref it since we don't need it anymore } diff --git a/src/implementations/cairo-dock-X-utilities.c b/src/implementations/cairo-dock-X-utilities.c index 26217dabc..13af72f50 100644 --- a/src/implementations/cairo-dock-X-utilities.c +++ b/src/implementations/cairo-dock-X-utilities.c @@ -1165,11 +1165,9 @@ gchar *cairo_dock_get_xwindow_class (Window Xid, gchar **cWMClass) cClass = g_ascii_strdown (pClassHint->res_class, -1); // down case because some apps change the case depending of their windows... } + if (g_str_has_suffix (cClass, ".exe")) cClass[strlen (cClass) - 4] = 0; + else if (g_str_has_suffix (cClass, ".py")) cClass[strlen (cClass) - 3] = 0; cairo_dock_remove_version_from_string (cClass); // we remore number of version (e.g. Openoffice.org-3.1) - - gchar *str = strchr (cClass, '.'); // we remove all .xxx otherwise we can't detect the lack of extension when looking for an icon (openoffice.org) or it's a problem when looking for an icon (jbrout.py). - if (str != NULL) - *str = '\0'; cd_debug ("got an application with class '%s'", cClass); XFree (pClassHint->res_name); @@ -1581,7 +1579,7 @@ cairo_surface_t *cairo_dock_create_surface_from_xpixmap (Pixmap Xid, int iWidth, GdkPixbuf *pPixbuf = cairo_dock_get_pixbuf_from_pixmap (Xid, TRUE); if (pPixbuf == NULL) { - cd_warning ("No thumbnail available.\nEither the WM doesn't support this functionnality, or the window was minimized when the dock has been launched."); + cd_warning ("No thumbnail available.\nEither the WM doesn't support this explicitly, or the window was minimized when the dock has been launched."); return NULL; } diff --git a/tests/config.py b/tests/config.py index 51166b200..eb7cfe5d9 100644 --- a/tests/config.py +++ b/tests/config.py @@ -1,10 +1,7 @@ -#exe = 'galculator' # name of a program that can be launched several times, and is usually not running -#wmclass = 'galculator' # its class -#desktop_file = 'fedora-galculator.desktop' # its desktop file exe = 'gnome-calculator' # name of a program that can be launched several times, and is usually not running wmclass = 'gnome-calculator' # its class -desktop_file = 'gcalctool.desktop' # its desktop file +desktop_file = 'gnome-calculator.desktop' # its desktop file exe1 = 'gnome-session-properties' # a program that doesn't have a launcher yet wmclass1 = 'gnome-session-properties' # its class