Back to index

indicator-appmenu  12.10.0
Classes | Defines | Typedefs | Functions
hudwindowsource.c File Reference
#include "hudwindowsource.h"
#include <libbamf/libbamf.h>
#include <string.h>
#include "hudmenumodelcollector.h"
#include "huddbusmenucollector.h"
#include "hudsource.h"

Go to the source code of this file.

Classes

struct  _HudWindowSource
 SECTION:hudwindowsource : HudWindowSource : a #HudSource for the menubars of windows. More...

Defines

#define G_LOG_DOMAIN   "hudwindowsource"

Typedefs

typedef GObjectClass HudWindowSourceClass

Functions

static void hud_window_source_iface_init (HudSourceInterface *iface)
 G_DEFINE_TYPE_WITH_CODE (HudWindowSource, hud_window_source, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(HUD_TYPE_SOURCE, hud_window_source_iface_init))
static gboolean hud_window_source_name_in_ignore_list (BamfWindow *window)
static HudSource * hud_window_source_get_collector (HudWindowSource *source)
static void hud_window_source_collector_changed (HudSource *collector, gpointer user_data)
static void hud_window_source_active_window_changed (BamfMatcher *matcher, BamfView *oldview, BamfView *newview, gpointer user_data)
static void hud_window_source_use (HudSource *hud_source)
static void hud_window_source_unuse (HudSource *hud_source)
static void hud_window_source_search (HudSource *hud_source, GPtrArray *results_array, HudTokenList *search_string)
static void hud_window_source_finalize (GObject *object)
static void hud_window_source_init (HudWindowSource *source)
static void hud_window_source_class_init (HudWindowSourceClass *class)
HudWindowSource * hud_window_source_new (void)
 hud_window_source_new:

Class Documentation

struct _HudWindowSource

SECTION:hudwindowsource : HudWindowSource : a #HudSource for the menubars of windows.

HudWindowSource is a #HudSource that allows searching for items in

the menubars of application windows.

The source tracks which is the active window of the application, using BAMF. hud_source_search() calls will be redirected to an appropriate source corresponding to the active window. When the active window changes, the HudSource::changed signal will be emitted.

GMenuModel and Dbusmenu-style menus are both understood. They are

implemented via #HudMenuModelCollector and #HudDbusmenuCollector, respectively.

HudWindowSource takes care to avoid various bits of desktop chrome

from becoming considered as the active window. This is done via a built-in blacklist. It is also possible, for testing purposes, to use the <envar>INDICATOR_APPMENU_DEBUG_APPS</envar> environment variable to specify a list of desktop file names corresponding to applications to ignore windows from (for example, the terminal). HudWindowSource:

This is an opaque structure type.

Definition at line 61 of file hudwindowsource.c.

Class Members
BamfApplication * active_application
HudSource * active_collector
const gchar * active_desktop_file
gchar * active_icon
BamfWindow * active_window
BamfMatcher * matcher
GObject parent_instance
gint use_count

Define Documentation

#define G_LOG_DOMAIN   "hudwindowsource"

Definition at line 19 of file hudwindowsource.c.


Typedef Documentation

typedef GObjectClass HudWindowSourceClass

Definition at line 75 of file hudwindowsource.c.


Function Documentation

G_DEFINE_TYPE_WITH_CODE ( HudWindowSource  ,
hud_window_source  ,
G_TYPE_OBJECT  ,
G_IMPLEMENT_INTERFACE(HUD_TYPE_SOURCE, hud_window_source_iface_init  
)

Definition at line 78 of file hudwindowsource.c.

{
  static GStrv debug_list = NULL;
  gint i;

  /* Looks at the envvar to see if there is a list of items that we shouldn't
     view as focus changes so that we can use those tools for debugging */
  if (debug_list == NULL)
    {
      const gchar * dbgenv = g_getenv ("INDICATOR_APPMENU_DEBUG_APPS");
      if (dbgenv != NULL)
        debug_list = g_strsplit (dbgenv, ":", 0);
      else
        debug_list = g_new0 (gchar *, 1);
    }

  g_debug ("checking desktop file '%s'", desktop_file);

  for (i = 0; debug_list[i] != NULL; i++)
    if (debug_list[i][0] != '\0' && strstr (desktop_file, debug_list[i]))
      {
        g_debug ("desktop file name '%s' blocked (hit debug list item '%s')", desktop_file, debug_list[i]);
        return TRUE;
      }

  return FALSE;
}
static void hud_window_source_active_window_changed ( BamfMatcher *  matcher,
BamfView *  oldview,
BamfView *  newview,
gpointer  user_data 
) [static]

Definition at line 197 of file hudwindowsource.c.

{
  HudWindowSource *source = user_data;
  BamfWindow *window;
  BamfApplication *application;
  const gchar *desktop_file;

  g_debug ("Switching windows");

  if (!BAMF_IS_WINDOW (newview))
    {
      g_debug ("ignoring switch to non-window");
      return;
    }

  window = BAMF_WINDOW (newview);

  if (window == source->active_window)
    {
      g_debug ("this is already the active window");
      return;
    }

  if (hud_window_source_name_in_ignore_list (window))
    return;

  application = bamf_matcher_get_application_for_window (source->matcher, window);

  if (application == NULL)
    {
      g_debug ("ignoring window with no application");
      return;
    }

  desktop_file = bamf_application_get_desktop_file (application);

  if (desktop_file == NULL)
    {
      g_debug ("ignoring application with no desktop file");
      return;
    }

  if (hud_window_source_desktop_file_in_debug_list (desktop_file))
    return;

  g_debug ("new active window (xid %u)", bamf_window_get_xid (window));


  if (source->active_collector)
    {
      g_signal_handlers_disconnect_by_func (source->active_collector, hud_window_source_collector_changed, source);
      if (source->use_count)
        hud_source_unuse (source->active_collector);
    }

  g_clear_object (&source->active_collector);
  g_clear_object (&source->active_application);
  g_clear_object (&source->active_window);
  g_free (source->active_icon);
  source->active_window = g_object_ref (window);
  source->active_application = g_object_ref (application);
  source->active_desktop_file = desktop_file;
  source->active_icon = bamf_view_get_icon (BAMF_VIEW (application));
  source->active_collector = g_object_ref (hud_window_source_get_collector (source));

  if (source->use_count)
    hud_source_use (source->active_collector);
  g_signal_connect_object (source->active_collector, "changed",
                           G_CALLBACK (hud_window_source_collector_changed), source, 0);

  hud_source_changed (HUD_SOURCE (source));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void hud_window_source_class_init ( HudWindowSourceClass class) [static]

Definition at line 350 of file hudwindowsource.c.

{
  class->finalize = hud_window_source_finalize;
}

Here is the call graph for this function:

static void hud_window_source_collector_changed ( HudSource *  collector,
gpointer  user_data 
) [static]

Definition at line 188 of file hudwindowsource.c.

{
  HudWindowSource *source = user_data;

  hud_source_changed (HUD_SOURCE (source));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void hud_window_source_finalize ( GObject *  object) [static]

Definition at line 311 of file hudwindowsource.c.

{
  HudWindowSource *source = HUD_WINDOW_SOURCE (object);

  g_assert_cmpint (source->use_count, ==, 0);

  /* bamf matcher signals already disconnected in dispose */
  g_clear_object (&source->active_collector);
  g_clear_object (&source->active_application);
  g_clear_object (&source->active_window);
  g_free (source->active_icon);

  G_OBJECT_CLASS (hud_window_source_parent_class)
    ->finalize (object);
}

Here is the caller graph for this function:

static HudSource* hud_window_source_get_collector ( HudWindowSource *  source) [static]

Definition at line 149 of file hudwindowsource.c.

{
  static GQuark menu_collector_quark;
  HudSource *collector;

  if (source->active_window == NULL)
    return NULL;

  if (!menu_collector_quark)
    menu_collector_quark = g_quark_from_string ("menu collector");

  collector = g_object_get_qdata (G_OBJECT (source->active_window), menu_collector_quark);
  if (collector == NULL)
    {
      HudMenuModelCollector *menumodel_collector;

      /* GMenuModel menus either exist at the start or will never exist.
       * dbusmenu menus can appear later.
       *
       * For that reason, we check first for GMenuModel and assume if it
       * doesn't exist then it must be dbusmenu.
       */
      menumodel_collector = hud_menu_model_collector_get (source->active_window,
                                                          source->active_desktop_file,
                                                          source->active_icon);
      if (menumodel_collector)
        collector = HUD_SOURCE (menumodel_collector);
      else
        collector = HUD_SOURCE (hud_dbusmenu_collector_new_for_window (source->active_window,
                                                                       source->active_desktop_file,
                                                                       source->active_icon));

      g_object_set_qdata_full (G_OBJECT (source->active_window), menu_collector_quark, collector, g_object_unref);
    }

  return collector;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void hud_window_source_iface_init ( HudSourceInterface *  iface) [static]

Definition at line 342 of file hudwindowsource.c.

{
  iface->use = hud_window_source_use;
  iface->unuse = hud_window_source_unuse;
  iface->search = hud_window_source_search;
}

Here is the call graph for this function:

static void hud_window_source_init ( HudWindowSource *  source) [static]

Definition at line 328 of file hudwindowsource.c.

{
  BamfWindow *window;

  source->matcher = bamf_matcher_get_default ();

  g_signal_connect_object (source->matcher, "active-window-changed",
                           G_CALLBACK (hud_window_source_active_window_changed), source, 0);
  window = bamf_matcher_get_active_window (source->matcher);
  if (window != NULL)
    hud_window_source_active_window_changed (source->matcher, NULL, BAMF_VIEW (window), source);
}

Here is the call graph for this function:

static gboolean hud_window_source_name_in_ignore_list ( BamfWindow *  window) [static]

Definition at line 111 of file hudwindowsource.c.

{
  static const gchar * const ignored_names[] = {
    "Hud Prototype Test",
    "Hud",
    "DNDCollectionWindow",
    "launcher",
    "dash",
    "Dash",
    "panel",
    "hud",
    "unity-2d-shell"
  };
  gboolean ignored = FALSE;
  gchar *window_name;
  gint i;

  window_name = bamf_view_get_name (BAMF_VIEW (window));
  g_debug ("checking window name '%s'", window_name);

  /* sometimes bamf returns NULL here... protect ourselves */
  if (window_name == NULL)
    return TRUE;

  for (i = 0; i < G_N_ELEMENTS (ignored_names); i++)
    if (g_str_equal (ignored_names[i], window_name))
      {
        g_debug ("window name '%s' blocked", window_name);
        ignored = TRUE;
        break;
      }

  g_free (window_name);

  return ignored;
}

Here is the caller graph for this function:

HudWindowSource* hud_window_source_new ( void  )

hud_window_source_new:

Creates a #HudWindowSource.

Returns: a new #HudWindowSource

Definition at line 363 of file hudwindowsource.c.

{
  return g_object_new (HUD_TYPE_WINDOW_SOURCE, NULL);
}

Here is the caller graph for this function:

static void hud_window_source_search ( HudSource *  hud_source,
GPtrArray *  results_array,
HudTokenList *  search_string 
) [static]

Definition at line 300 of file hudwindowsource.c.

{
  HudWindowSource *source = HUD_WINDOW_SOURCE (hud_source);

  if (source->active_collector)
    hud_source_search (source->active_collector, results_array, search_string);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void hud_window_source_unuse ( HudSource *  hud_source) [static]

Definition at line 286 of file hudwindowsource.c.

{
  HudWindowSource *source = HUD_WINDOW_SOURCE (hud_source);

  g_return_if_fail (source->use_count > 0);

  source->use_count--;

  if (source->use_count == 0)
    if (source->active_collector)
      hud_source_unuse (source->active_collector);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void hud_window_source_use ( HudSource *  hud_source) [static]

Definition at line 274 of file hudwindowsource.c.

{
  HudWindowSource *source = HUD_WINDOW_SOURCE (hud_source);

  if (source->use_count == 0)
    if (source->active_collector)
      hud_source_use (source->active_collector);

  source->use_count++;
}

Here is the call graph for this function:

Here is the caller graph for this function: