Merge lp:~3v1n0/bamf/better-wmclass-filter into lp:bamf/0.4

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Marco Trevisan (Treviño)
Approved revision: 479
Merged at revision: 466
Proposed branch: lp:~3v1n0/bamf/better-wmclass-filter
Merge into: lp:bamf/0.4
Prerequisite: lp:~3v1n0/bamf/desktopless-webapps-fix
Diff against target: 434 lines (+140/-75)
3 files modified
src/bamf-application.c (+29/-19)
src/bamf-matcher.c (+108/-56)
src/bamf-matcher.h (+3/-0)
To merge this branch: bzr merge lp:~3v1n0/bamf/better-wmclass-filter
Reviewer Review Type Date Requested Status
Jason Smith (community) Approve
Review via email: mp+104036@code.launchpad.net

Commit message

BamfMatcher: use both instance and class names for matching WMClass

Also, filter out the .desktop files that have a defined StartupWMClass
that doesn't match with our .desktop file.

Description of the change

We use both WMClass instance and class name to match proper .desktop files, also we filter out from possible_desktop list the .desktop files that have defined a wmclass that does not match with the one of the target window.

This allow to make both the custom applications .desktop files to work correctly and the web applications to be matched as new ones.

Plus, favorites are used only if their class matches.

To post a comment you must log in.
Revision history for this message
Jason Smith (jassmith) wrote :

Looks good, nothing too scary.

review: Approve
Revision history for this message
Unity Merger (unity-merger) wrote :

The prerequisite lp:~3v1n0/bamf/desktopless-webapps-fix has not yet been merged into lp:bamf.

Revision history for this message
Unity Merger (unity-merger) wrote :

Attempt to merge into lp:bamf failed due to conflicts:

text conflict in src/bamf-matcher.c

lp:~3v1n0/bamf/better-wmclass-filter updated
479. By Marco Trevisan (Treviño)

Merging with trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/bamf-application.c'
--- src/bamf-application.c 2012-04-26 06:16:01 +0000
+++ src/bamf-application.c 2012-05-22 16:24:22 +0000
@@ -120,17 +120,20 @@
120 if (self->priv->desktop_file)120 if (self->priv->desktop_file)
121 {121 {
122 keyfile = g_key_file_new();122 keyfile = g_key_file_new();
123 if (!g_key_file_load_from_file(keyfile, self->priv->desktop_file, G_KEY_FILE_NONE, NULL)) {123
124 if (!g_key_file_load_from_file(keyfile, self->priv->desktop_file, G_KEY_FILE_NONE, NULL))
125 {
124 g_key_file_free(keyfile);126 g_key_file_free(keyfile);
125 return;127 return;
126 }128 }
127129
128 desktop = g_desktop_app_info_new_from_keyfile (keyfile);130 desktop = g_desktop_app_info_new_from_keyfile (keyfile);
129131
130 if (!G_IS_APP_INFO (desktop)) {132 if (!G_IS_APP_INFO (desktop))
131 g_key_file_free(keyfile);133 {
132 return;134 g_key_file_free(keyfile);
133 }135 return;
136 }
134137
135 gicon = g_app_info_get_icon (G_APP_INFO (desktop));138 gicon = g_app_info_get_icon (G_APP_INFO (desktop));
136139
@@ -139,14 +142,15 @@
139 if (gicon)142 if (gicon)
140 icon = g_icon_to_string (gicon);143 icon = g_icon_to_string (gicon);
141144
142 if (g_key_file_has_key(keyfile, G_KEY_FILE_DESKTOP_GROUP, STUB_KEY, NULL)) {145 if (g_key_file_has_key(keyfile, G_KEY_FILE_DESKTOP_GROUP, STUB_KEY, NULL))
143 /* This will error to return false, which is okay as it seems146 {
144 unlikely anyone will want to set this flag except to turn147 /* This will error to return false, which is okay as it seems
145 off the stub menus. */148 unlikely anyone will want to set this flag except to turn
146 self->priv->show_stubs = g_key_file_get_boolean (keyfile,149 off the stub menus. */
147 G_KEY_FILE_DESKTOP_GROUP,150 self->priv->show_stubs = g_key_file_get_boolean (keyfile,
148 STUB_KEY, NULL);151 G_KEY_FILE_DESKTOP_GROUP,
149 }152 STUB_KEY, NULL);
153 }
150 154
151 if (g_key_file_has_key (keyfile, G_KEY_FILE_DESKTOP_GROUP, "X-GNOME-FullName", NULL))155 if (g_key_file_has_key (keyfile, G_KEY_FILE_DESKTOP_GROUP, "X-GNOME-FullName", NULL))
152 {156 {
@@ -489,11 +493,12 @@
489}493}
490494
491static char *495static char *
492bamf_application_favorite_from_list (BamfApplication *self, GList *list)496bamf_application_favorite_from_list (BamfApplication *self, GList *desktop_list)
493{497{
494 BamfMatcher *matcher;498 BamfMatcher *matcher;
495 GList *favs, *l;499 GList *favs, *l;
496 char *result = NULL;500 char *result = NULL;
501 const char *desktop_class;
497502
498 g_return_val_if_fail (BAMF_IS_APPLICATION (self), NULL);503 g_return_val_if_fail (BAMF_IS_APPLICATION (self), NULL);
499504
@@ -504,10 +509,15 @@
504 {509 {
505 for (l = favs; l; l = l->next)510 for (l = favs; l; l = l->next)
506 {511 {
507 if (g_list_find_custom (list, l->data, (GCompareFunc) g_strcmp0))512 if (g_list_find_custom (desktop_list, l->data, (GCompareFunc) g_strcmp0))
508 {513 {
509 result = l->data;514 desktop_class = bamf_matcher_get_desktop_file_class (matcher, l->data);
510 break;515
516 if (!desktop_class || g_strcmp0 (self->priv->wmclass, desktop_class) == 0)
517 {
518 result = l->data;
519 break;
520 }
511 }521 }
512 }522 }
513 }523 }
514524
=== modified file 'src/bamf-matcher.c'
--- src/bamf-matcher.c 2012-05-22 15:10:26 +0000
+++ src/bamf-matcher.c 2012-05-22 16:24:22 +0000
@@ -659,9 +659,11 @@
659}659}
660660
661static gboolean661static gboolean
662exec_string_should_be_processed (BamfMatcher *self,662exec_string_should_be_processed (const char *exec)
663 char *exec)
664{663{
664 if (!exec)
665 return TRUE;
666
665 return !g_str_has_prefix (exec, "ooffice") && !g_str_has_prefix (exec, "libreoffice");667 return !g_str_has_prefix (exec, "ooffice") && !g_str_has_prefix (exec, "libreoffice");
666}668}
667669
@@ -829,7 +831,7 @@
829 return;831 return;
830 }832 }
831833
832 if (exec_string_should_be_processed (self, exec))834 if (exec_string_should_be_processed (exec))
833 {835 {
834 /**836 /**
835 * Set of nasty hacks which should be removed some day. We wish to keep the full exec837 * Set of nasty hacks which should be removed some day. We wish to keep the full exec
@@ -939,7 +941,7 @@
939 gchar **parts = g_strsplit (line, "\t", 3);941 gchar **parts = g_strsplit (line, "\t", 3);
940 exec = parts[1];942 exec = parts[1];
941943
942 if (exec_string_should_be_processed (self, exec))944 if (exec_string_should_be_processed (exec))
943 {945 {
944 char *tmp = trim_exec_string (self, exec);946 char *tmp = trim_exec_string (self, exec);
945 g_free (parts[1]);947 g_free (parts[1]);
@@ -1377,6 +1379,9 @@
1377{1379{
1378 const char *class_name = bamf_legacy_window_get_class_name (window);1380 const char *class_name = bamf_legacy_window_get_class_name (window);
13791381
1382 if (!class_name)
1383 return FALSE;
1384
1380 return (g_str_has_prefix (class_name, "LibreOffice") ||1385 return (g_str_has_prefix (class_name, "LibreOffice") ||
1381 g_str_has_prefix (class_name, "libreoffice") ||1386 g_str_has_prefix (class_name, "libreoffice") ||
1382 g_str_has_prefix (class_name, "OpenOffice") ||1387 g_str_has_prefix (class_name, "OpenOffice") ||
@@ -1543,17 +1548,20 @@
15431548
1544 gboolean valid_app = FALSE;1549 gboolean valid_app = FALSE;
15451550
1546 if (g_strcmp0 (window_class, "Google-chrome") == 0 &&1551 if (instance_name && window_class)
1547 g_strcmp0 (instance_name, "google-chrome") != 0 &&1552 {
1548 !g_str_has_prefix (instance_name, "Google-chrome"))1553 if (g_strcmp0 (window_class, "Google-chrome") == 0 &&
1549 {1554 g_strcmp0 (instance_name, "google-chrome") != 0 &&
1550 valid_app = TRUE;1555 !g_str_has_prefix (instance_name, "Google-chrome"))
1551 }1556 {
1552 else if (g_strcmp0 (window_class, "Chromium-browser") == 0 &&1557 valid_app = TRUE;
1553 g_strcmp0 (instance_name, "chromium-browser") != 0 &&1558 }
1554 !g_str_has_prefix (instance_name, "Chromium-browser"))1559 else if (g_strcmp0 (window_class, "Chromium-browser") == 0 &&
1555 {1560 g_strcmp0 (instance_name, "chromium-browser") != 0 &&
1556 valid_app = TRUE;1561 !g_str_has_prefix (instance_name, "Chromium-browser"))
1562 {
1563 valid_app = TRUE;
1564 }
1557 }1565 }
15581566
1559 return valid_app;1567 return valid_app;
@@ -1620,36 +1628,50 @@
16201628
1621static GList *1629static GList *
1622bamf_matcher_possible_applications_for_window (BamfMatcher *self,1630bamf_matcher_possible_applications_for_window (BamfMatcher *self,
1623 BamfWindow *bamf_window)1631 BamfWindow *bamf_window,
1632 const char **target_class_out)
1624{1633{
1625 BamfMatcherPrivate *priv;1634 BamfMatcherPrivate *priv;
1626 BamfLegacyWindow *window;1635 BamfLegacyWindow *window;
1627 GList *desktop_files = NULL, *l;1636 GList *desktop_files = NULL, *l;
1628 char *desktop_file = NULL;1637 char *desktop_file = NULL;
1629 char *desktop_class = NULL;1638 const char *desktop_class = NULL;
1639 const char *class_name = NULL;
1640 const char *instance_name = NULL;
1641 const char *target_class = NULL;
1642 gboolean filter_by_wmclass = FALSE;
16301643
1631 g_return_val_if_fail (BAMF_IS_WINDOW (bamf_window), NULL);1644 g_return_val_if_fail (BAMF_IS_WINDOW (bamf_window), NULL);
1632 g_return_val_if_fail (BAMF_IS_MATCHER (self), NULL);1645 g_return_val_if_fail (BAMF_IS_MATCHER (self), NULL);
16331646
1634 priv = self->priv;1647 priv = self->priv;
1635 window = bamf_window_get_window (bamf_window);1648 window = bamf_window_get_window (bamf_window);
1636
1637 desktop_file = get_window_hint (window, _NET_WM_DESKTOP_FILE);1649 desktop_file = get_window_hint (window, _NET_WM_DESKTOP_FILE);
16381650 class_name = bamf_legacy_window_get_class_name (window);
1639 const char *class_name = bamf_legacy_window_get_class_name (window);1651 instance_name = bamf_legacy_window_get_class_instance_name (window);
1640 const char *instance_name = bamf_legacy_window_get_class_instance_name (window);1652
1641 gboolean known_desktop_class = bamf_matcher_has_instance_class_desktop_file (self, instance_name);1653 target_class = instance_name;
16421654 filter_by_wmclass = bamf_matcher_has_instance_class_desktop_file (self, target_class);
1643 if (!known_desktop_class)1655
1656 if (!filter_by_wmclass)
1644 {1657 {
1645 known_desktop_class = is_web_app_window (self, window);1658 if (is_web_app_window (self, window))
1659 {
1660 // This ensures that a new application is created even for unknown webapps
1661 filter_by_wmclass = TRUE;
1662 }
1663 else
1664 {
1665 target_class = class_name;
1666 filter_by_wmclass = bamf_matcher_has_instance_class_desktop_file (self, target_class);
1667 }
1646 }1668 }
16471669
1648 if (desktop_file)1670 if (desktop_file)
1649 {1671 {
1650 desktop_class = g_hash_table_lookup (priv->desktop_class_table, desktop_file);1672 desktop_class = bamf_matcher_get_desktop_file_class (self, desktop_file);
16511673
1652 if (!known_desktop_class || g_strcmp0 (desktop_class, instance_name) == 0)1674 if ((!filter_by_wmclass && !desktop_class) || g_strcmp0 (desktop_class, target_class) == 0)
1653 {1675 {
1654 desktop_files = g_list_prepend (desktop_files, desktop_file);1676 desktop_files = g_list_prepend (desktop_files, desktop_file);
1655 }1677 }
@@ -1675,9 +1697,9 @@
16751697
1676 if (desktop_file)1698 if (desktop_file)
1677 {1699 {
1678 desktop_class = g_hash_table_lookup (priv->desktop_class_table, desktop_file);1700 desktop_class = bamf_matcher_get_desktop_file_class (self, desktop_file);
16791701
1680 if (!known_desktop_class || g_strcmp0 (desktop_class, instance_name) == 0)1702 if ((!filter_by_wmclass && !desktop_class) || g_strcmp0 (desktop_class, target_class) == 0)
1681 {1703 {
1682 if (!g_list_find_custom (desktop_files, desktop_file,1704 if (!g_list_find_custom (desktop_files, desktop_file,
1683 (GCompareFunc) g_strcmp0))1705 (GCompareFunc) g_strcmp0))
@@ -1708,10 +1730,10 @@
1708 {1730 {
1709 gboolean append = FALSE;1731 gboolean append = FALSE;
17101732
1711 if (instance_name)1733 if (target_class)
1712 {1734 {
1713 desktop_class = g_hash_table_lookup (priv->desktop_class_table, desktop_file);1735 desktop_class = bamf_matcher_get_desktop_file_class (self, desktop_file);
1714 if (!known_desktop_class || g_strcmp0 (desktop_class, instance_name) == 0)1736 if ((!filter_by_wmclass && !desktop_class) || g_strcmp0 (desktop_class, target_class) == 0)
1715 {1737 {
1716 append = TRUE;1738 append = TRUE;
1717 }1739 }
@@ -1753,34 +1775,40 @@
1753 g_list_free (pid_list);1775 g_list_free (pid_list);
1754 }1776 }
17551777
1756 if (!desktop_files && known_desktop_class)1778 if (!desktop_files && filter_by_wmclass)
1757 {1779 {
1758 desktop_files = bamf_matcher_get_class_matching_desktop_files (self, instance_name);1780 desktop_files = bamf_matcher_get_class_matching_desktop_files (self, target_class);
1781 }
1782
1783 if (target_class_out)
1784 {
1785 *target_class_out = target_class;
1759 }1786 }
17601787
1761 return desktop_files;1788 return desktop_files;
1762}1789}
17631790
1764static void1791static BamfApplication *
1765bamf_matcher_setup_window_state (BamfMatcher *self,1792bamf_matcher_get_application_for_window (BamfMatcher *self,
1766 BamfWindow *bamf_window)1793 BamfWindow *bamf_window,
1794 gboolean *new_application)
1767{1795{
1768 GList *possible_apps, *l;1796 GList *possible_apps, *l;
1769 BamfLegacyWindow *window;1797 BamfLegacyWindow *window;
1770 const gchar *app_class;1798 const gchar *win_class_name;
1799 const gchar *target_class = NULL;
1800 const gchar *app_class = NULL;
1771 const gchar *app_desktop = NULL;1801 const gchar *app_desktop = NULL;
1772 BamfApplication *app = NULL, *best = NULL;1802 BamfApplication *app = NULL, *best = NULL;
17731803
1774 g_return_if_fail (BAMF_IS_MATCHER (self));1804 g_return_val_if_fail (BAMF_IS_MATCHER (self), NULL);
1775 g_return_if_fail (BAMF_IS_WINDOW (bamf_window));1805 g_return_val_if_fail (BAMF_IS_WINDOW (bamf_window), NULL);
17761806
1777 window = bamf_window_get_window (bamf_window);1807 window = bamf_window_get_window (bamf_window);
17781808 win_class_name = bamf_legacy_window_get_class_name (window);
1779 possible_apps = bamf_matcher_possible_applications_for_window (self, bamf_window);1809
1780 const char *win_instance = bamf_legacy_window_get_class_instance_name (window);1810 possible_apps = bamf_matcher_possible_applications_for_window (self, bamf_window, &target_class);
1781 const char *win_class_name = bamf_legacy_window_get_class_name (window);1811 app_class = target_class;
1782
1783 app_class = win_instance;
17841812
1785 /* Loop over every possible desktop file that could match the window, and try1813 /* Loop over every possible desktop file that could match the window, and try
1786 * to reuse an already-opened window that uses it.1814 * to reuse an already-opened window that uses it.
@@ -1799,7 +1827,7 @@
1799 const gchar *app_desktop_class;1827 const gchar *app_desktop_class;
1800 app_desktop_class = bamf_application_get_wmclass (app);1828 app_desktop_class = bamf_application_get_wmclass (app);
18011829
1802 if (win_instance && app_desktop_class && strcasecmp (win_instance, app_desktop_class) == 0)1830 if (target_class && app_desktop_class && strcasecmp (target_class, app_desktop_class) == 0)
1803 {1831 {
1804 best = app;1832 best = app;
1805 break;1833 break;
@@ -1829,7 +1857,7 @@
1829 const gchar *best_desktop_class;1857 const gchar *best_desktop_class;
18301858
1831 best_app_class = bamf_application_get_wmclass (best);1859 best_app_class = bamf_application_get_wmclass (best);
1832 best_desktop_class = g_hash_table_lookup (self->priv->desktop_class_table, best_desktop);1860 best_desktop_class = bamf_matcher_get_desktop_file_class (self, best_desktop);
18331861
1834 /* We compare the two classes using their "distance" from the1862 /* We compare the two classes using their "distance" from the
1835 * desidered class value */1863 * desidered class value */
@@ -1867,7 +1895,7 @@
18671895
1868 if (bamf_application_contains_similar_to_window (app, bamf_window))1896 if (bamf_application_contains_similar_to_window (app, bamf_window))
1869 {1897 {
1870 if (win_instance && g_strcmp0 (win_instance, app_desktop_class) == 0)1898 if (target_class && g_strcmp0 (target_class, app_desktop_class) == 0)
1871 {1899 {
1872 best = app;1900 best = app;
1873 break;1901 break;
@@ -1896,12 +1924,19 @@
1896 }1924 }
18971925
1898 bamf_application_set_wmclass (best, app_class);1926 bamf_application_set_wmclass (best, app_class);
1899 bamf_matcher_register_view_stealing_ref (self, BAMF_VIEW (best));
1900 }
19011927
1902 bamf_view_add_child (BAMF_VIEW (best), BAMF_VIEW (bamf_window));1928 if (new_application)
1929 *new_application = TRUE;
1930 }
1931 else
1932 {
1933 if (new_application)
1934 *new_application = FALSE;
1935 }
19031936
1904 g_list_free_full (possible_apps, g_free);1937 g_list_free_full (possible_apps, g_free);
1938
1939 return best;
1905}1940}
19061941
1907/* Ensures that the window hint is set if a registered pid matches, and that set window hints1942/* Ensures that the window hint is set if a registered pid matches, and that set window hints
@@ -1972,6 +2007,7 @@
1972handle_raw_window (BamfMatcher *self, BamfLegacyWindow *window)2007handle_raw_window (BamfMatcher *self, BamfLegacyWindow *window)
1973{2008{
1974 BamfWindow *bamfwindow;2009 BamfWindow *bamfwindow;
2010 BamfApplication *bamfapplication;
19752011
1976 g_return_if_fail (BAMF_IS_MATCHER (self));2012 g_return_if_fail (BAMF_IS_MATCHER (self));
1977 g_return_if_fail (BAMF_IS_LEGACY_WINDOW (window));2013 g_return_if_fail (BAMF_IS_LEGACY_WINDOW (window));
@@ -1989,7 +2025,15 @@
1989 bamfwindow = bamf_window_new (window);2025 bamfwindow = bamf_window_new (window);
1990 bamf_matcher_register_view_stealing_ref (self, BAMF_VIEW (bamfwindow));2026 bamf_matcher_register_view_stealing_ref (self, BAMF_VIEW (bamfwindow));
19912027
1992 bamf_matcher_setup_window_state (self, bamfwindow);2028 gboolean new_app = FALSE;
2029 bamfapplication = bamf_matcher_get_application_for_window (self, bamfwindow, &new_app);
2030
2031 if (new_app)
2032 {
2033 bamf_matcher_register_view_stealing_ref (self, BAMF_VIEW (bamfapplication));
2034 }
2035
2036 bamf_view_add_child (BAMF_VIEW (bamfapplication), BAMF_VIEW (bamfwindow));
1993}2037}
19942038
1995static void2039static void
@@ -2243,6 +2287,15 @@
2243 }2287 }
2244}2288}
22452289
2290const char *
2291bamf_matcher_get_desktop_file_class (BamfMatcher * self, const char * desktop_file)
2292{
2293 g_return_val_if_fail (BAMF_IS_MATCHER (self), NULL);
2294 g_return_val_if_fail (desktop_file, NULL);
2295
2296 return g_hash_table_lookup (self->priv->desktop_class_table, desktop_file);
2297}
2298
2246static int2299static int
2247x_error_handler (Display *display, XErrorEvent *event)2300x_error_handler (Display *display, XErrorEvent *event)
2248{2301{
@@ -2347,7 +2400,6 @@
2347 return (idx_a < idx_b) ? -1 : 1;2400 return (idx_a < idx_b) ? -1 : 1;
2348}2401}
23492402
2350
2351GVariant *2403GVariant *
2352bamf_matcher_get_window_stack_for_monitor (BamfMatcher *matcher, gint monitor)2404bamf_matcher_get_window_stack_for_monitor (BamfMatcher *matcher, gint monitor)
2353{2405{
@@ -2515,8 +2567,8 @@
2515 if (g_list_find_custom (priv->favorites, fav, (GCompareFunc) g_strcmp0))2567 if (g_list_find_custom (priv->favorites, fav, (GCompareFunc) g_strcmp0))
2516 continue;2568 continue;
25172569
2570 bamf_matcher_load_desktop_file (matcher, fav);
2518 priv->favorites = g_list_prepend (priv->favorites, g_strdup (fav));2571 priv->favorites = g_list_prepend (priv->favorites, g_strdup (fav));
2519 bamf_matcher_load_desktop_file (matcher, fav);
2520 }2572 }
25212573
2522 g_signal_emit (matcher, matcher_signals[FAVORITES_CHANGED], 0);2574 g_signal_emit (matcher, matcher_signals[FAVORITES_CHANGED], 0);
25232575
=== modified file 'src/bamf-matcher.h'
--- src/bamf-matcher.h 2012-01-21 00:29:55 +0000
+++ src/bamf-matcher.h 2012-05-22 16:24:22 +0000
@@ -74,6 +74,9 @@
74 const char *application,74 const char *application,
75 gint pid);75 gint pid);
7676
77const char * bamf_matcher_get_desktop_file_class (BamfMatcher * self,
78 const char * desktop_file);
79
77const char * bamf_matcher_get_active_application (BamfMatcher *matcher);80const char * bamf_matcher_get_active_application (BamfMatcher *matcher);
7881
79const char * bamf_matcher_get_active_window (BamfMatcher *matcher);82const char * bamf_matcher_get_active_window (BamfMatcher *matcher);

Subscribers

People subscribed via source and target branches