Verified Commit bdcfc2ae authored by Zander Brown's avatar Zander Brown
Browse files

launcher: import app-list-model

Taken from my maynard fork
parent 5d5b55b1
/*
* Copyright © 2019 Zander Brown <zbrown@gnome.org>
*
* Inspired by gliststore.c:
* Copyright 2015 Lars Uebernickel
* Copyright 2015 Ryan Lortie
* https://gitlab.gnome.org/GNOME/glib/blob/713fec9dcb1ee49c4f64bbb6f483a5cd1db9966a/gio/gliststore.c
*
* SPDX-License-Identifier: GPL-3.0+
*/
#include "app-list-model.h"
#include <gio/gio.h>
typedef struct _PhoshAppListModelPrivate PhoshAppListModelPrivate;
struct _PhoshAppListModelPrivate {
GAppInfoMonitor *monitor;
GSequence *items;
gulong debounce;
/* cache */
struct {
gboolean is_valid;
guint position;
GSequenceIter *iter;
} last;
};
static void list_iface_init (GListModelInterface *iface);
G_DEFINE_TYPE_WITH_CODE (PhoshAppListModel, phosh_app_list_model, G_TYPE_OBJECT,
G_ADD_PRIVATE (PhoshAppListModel)
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_iface_init))
static void
phosh_app_list_model_finalize (GObject *object)
{
PhoshAppListModel *self = PHOSH_APP_LIST_MODEL (object);
PhoshAppListModelPrivate *priv = phosh_app_list_model_get_instance_private (self);
g_clear_object (&priv->monitor);
g_sequence_free (priv->items);
G_OBJECT_CLASS (phosh_app_list_model_parent_class)->finalize (object);
}
static void
phosh_app_list_model_class_init (PhoshAppListModelClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = phosh_app_list_model_finalize;
}
static GType
list_get_item_type (GListModel *list)
{
return G_TYPE_APP_INFO;
}
static gpointer
list_get_item (GListModel *list, guint position)
{
PhoshAppListModel *self = PHOSH_APP_LIST_MODEL (list);
PhoshAppListModelPrivate *priv = phosh_app_list_model_get_instance_private (self);
GSequenceIter *it = NULL;
if (priv->last.is_valid)
{
if (position < G_MAXUINT && priv->last.position == position + 1)
it = g_sequence_iter_prev (priv->last.iter);
else if (position > 0 && priv->last.position == position - 1)
it = g_sequence_iter_next (priv->last.iter);
else if (priv->last.position == position)
it = priv->last.iter;
}
if (it == NULL)
it = g_sequence_get_iter_at_pos (priv->items, position);
priv->last.iter = it;
priv->last.position = position;
priv->last.is_valid = TRUE;
if (g_sequence_iter_is_end (it))
return NULL;
else
return g_object_ref (g_sequence_get (it));
}
static unsigned int
list_get_n_items (GListModel *list)
{
PhoshAppListModel *self = PHOSH_APP_LIST_MODEL (list);
PhoshAppListModelPrivate *priv = phosh_app_list_model_get_instance_private (self);
return g_sequence_get_length (priv->items);
}
static void
list_iface_init (GListModelInterface *iface)
{
iface->get_item_type = list_get_item_type;
iface->get_item = list_get_item;
iface->get_n_items = list_get_n_items;
}
static gboolean
items_changed (gpointer data)
{
PhoshAppListModel *self = PHOSH_APP_LIST_MODEL (data);
PhoshAppListModelPrivate *priv = phosh_app_list_model_get_instance_private (self);
GList *new_apps;
int removed;
int added = 0;
new_apps = g_app_info_get_all ();
removed = g_sequence_get_length (priv->items);
g_sequence_remove_range (g_sequence_get_begin_iter (priv->items),
g_sequence_get_end_iter (priv->items));
while ((new_apps = g_list_next (new_apps))) {
if (!g_app_info_should_show (G_APP_INFO (new_apps->data))) {
continue;
}
g_sequence_append (priv->items, g_object_ref (new_apps->data));
added++;
}
g_list_free_full (new_apps, g_object_unref);
g_list_model_items_changed (G_LIST_MODEL (self), 0, removed, added);
priv->debounce = 0;
return G_SOURCE_REMOVE;
}
static void
on_monitor_changed_cb (GAppInfoMonitor *monitor,
gpointer data)
{
PhoshAppListModel *self = PHOSH_APP_LIST_MODEL (data);
PhoshAppListModelPrivate *priv = phosh_app_list_model_get_instance_private (self);
if (priv->debounce != 0) {
g_source_remove (priv->debounce);
}
priv->debounce = g_timeout_add (500, items_changed, data);
g_source_set_name_by_id (priv->debounce, "debounce app changes");
}
static void
phosh_app_list_model_init (PhoshAppListModel *self)
{
PhoshAppListModelPrivate *priv = phosh_app_list_model_get_instance_private (self);
priv->debounce = 0;
priv->items = g_sequence_new ((GDestroyNotify) g_object_unref);
priv->monitor = g_app_info_monitor_get ();
g_signal_connect (priv->monitor, "changed", G_CALLBACK (on_monitor_changed_cb), self);
on_monitor_changed_cb (priv->monitor, self);
}
/**
* phosh_app_list_model_get_default:
*
* Return Value: (transfer none): The global #PhoshAppListModel singleton
*/
PhoshAppListModel *
phosh_app_list_model_get_default (void)
{
static PhoshAppListModel *instance;
if (instance == NULL) {
instance = g_object_new (PHOSH_TYPE_APP_LIST_MODEL, NULL);
g_object_add_weak_pointer (G_OBJECT (instance), (gpointer *) &instance);
}
return instance;
}
/*
* Copyright © 2019 Zander Brown <zbrown@gnome.org>
*
* SPDX-License-Identifier: GPL-3.0+
*/
#include <gio/gio.h>
#include <gio/gdesktopappinfo.h>
#pragma once
G_BEGIN_DECLS
#define PHOSH_TYPE_APP_LIST_MODEL phosh_app_list_model_get_type()
G_DECLARE_DERIVABLE_TYPE (PhoshAppListModel, phosh_app_list_model, PHOSH, APP_LIST_MODEL, GObject)
struct _PhoshAppListModelClass
{
GObjectClass parent_class;
};
PhoshAppListModel *phosh_app_list_model_get_default (void);
G_END_DECLS
......@@ -33,6 +33,8 @@ libphosh_sources = [
'activity.h',
'app-grid-button.c',
'app-grid-button.h',
'app-list-model.c',
'app-list-model.h',
'favorites.c',
'favorites.h',
phosh_resources,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment