static void
track_window (ShellWindowTracker *self,
              MetaWindow      *window)
{
  ShellApp *app;

  if (!window_is_tracked (window))
    return;

  app = get_app_for_window (self, window);
  if (!app)
    return;

  /* At this point we've stored the association from window -> application */
  g_hash_table_insert (self->window_to_app, window, app);

  /* However, only put interesting windows in the window list for an app. */
  if (!shell_window_tracker_is_window_interesting (window))
    return;

  if (shell_app_is_transient (app))
    {
      /* For a transient application, it's possible one of our title regexps
       * will match at a later time, i.e. the application may not have set
       * its title fully at the time it initially maps a window.  Watch
       * for title changes and recompute the app.
       */
      g_signal_connect (window, "notify::title", G_CALLBACK (on_transient_window_title_changed), self);
    }

  _shell_app_add_window (app, window);

  if (shell_app_get_n_windows (app) == 1)
    {
      /* key is owned by the app */
      g_hash_table_insert (self->running_apps, (char*)shell_app_get_id (app),
                           app);
      g_signal_emit (self, signals[APP_RUNNING_CHANGED], 0, app);
    }

  g_signal_emit (self, signals[TRACKED_WINDOWS_CHANGED], 0);
}
static void
track_window (ShellWindowTracker *self,
              MetaWindow      *window)
{
  ShellApp *app;

  if (!shell_window_tracker_is_window_interesting (window))
    return;

  app = get_app_for_window (self, window);
  if (!app)
    return;

  /* At this point we've stored the association from window -> application */
  g_hash_table_insert (self->window_to_app, window, app);

  g_signal_connect (window, "notify::wm-class", G_CALLBACK (on_wm_class_changed), self);

  _shell_app_add_window (app, window);

  g_signal_emit (self, signals[TRACKED_WINDOWS_CHANGED], 0);
}
static void
disassociate_window (ShellWindowTracker   *self,
                     MetaWindow        *window)
{
  ShellApp *app;

  app = g_hash_table_lookup (self->window_to_app, window);
  if (!app)
    return;

  g_object_ref (app);

  g_hash_table_remove (self->window_to_app, window);

  if (shell_window_tracker_is_window_interesting (window))
    {
      _shell_app_remove_window (app, window);
      g_signal_handlers_disconnect_by_func (window, G_CALLBACK(on_wm_class_changed), self);
    }

  g_signal_emit (self, signals[TRACKED_WINDOWS_CHANGED], 0);

  g_object_unref (app);
}