/* AppSystem.c generated by valac 0.32.1, the Vala compiler
 * generated from AppSystem.vala, do not modify */

/*
 * This file is part of budgie-desktop
 *
 * Copyright (C) 2014-2016 Ikey Doherty <ikey@solus-project.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <gio/gdesktopappinfo.h>
#include <gio/gio.h>
#include <libwnck/libwnck.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/Xregion.h>


#define TYPE_APP_SYSTEM (app_system_get_type ())
#define APP_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_APP_SYSTEM, AppSystem))
#define APP_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_APP_SYSTEM, AppSystemClass))
#define IS_APP_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_APP_SYSTEM))
#define IS_APP_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_APP_SYSTEM))
#define APP_SYSTEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_APP_SYSTEM, AppSystemClass))

typedef struct _AppSystem AppSystem;
typedef struct _AppSystemClass AppSystemClass;
typedef struct _AppSystemPrivate AppSystemPrivate;
#define _g_hash_table_unref0(var) ((var == NULL) ? NULL : (var = (g_hash_table_unref (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define __g_list_free__g_object_unref0_0(var) ((var == NULL) ? NULL : (var = (_g_list_free__g_object_unref0_ (var), NULL)))

struct _AppSystem {
	GObject parent_instance;
	AppSystemPrivate * priv;
};

struct _AppSystemClass {
	GObjectClass parent_class;
};

struct _AppSystemPrivate {
	GHashTable* startupids;
	GHashTable* simpletons;
	GHashTable* desktops;
	GHashTable* exec_cache;
	GAppInfoMonitor* monitor;
	gchar** derpers;
	gint derpers_length1;
	gint _derpers_size_;
	gboolean invalidated;
	GRecMutex __lock_invalidated;
};


static gpointer app_system_parent_class = NULL;
static GType app_system_type_id = 0;

GType app_system_get_type (void) G_GNUC_CONST;
GType app_system_register_type (GTypeModule * module);
#define APP_SYSTEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_APP_SYSTEM, AppSystemPrivate))
enum  {
	APP_SYSTEM_DUMMY_PROPERTY
};
AppSystem* app_system_new (void);
AppSystem* app_system_construct (GType object_type);
static void _g_free0_ (gpointer var);
static void __lambda4_ (AppSystem* self);
static gboolean __lambda5_ (AppSystem* self);
static gboolean ___lambda5__gsource_func (gpointer self);
static void ___lambda4__g_app_info_monitor_changed (GAppInfoMonitor* _sender, gpointer self);
static void app_system_reload_ids (AppSystem* self);
gboolean app_system_has_derpy_icon (AppSystem* self, WnckWindow* window);
static gboolean _vala_string_array_contains (gchar** stack, int stack_length, gchar* needle);
static void app_system_check_invalidated (AppSystem* self);
static void _g_object_unref0_ (gpointer var);
static void _g_list_free__g_object_unref0_ (GList* self);
GDesktopAppInfo* app_system_query_window (AppSystem* self, WnckWindow* window);
gchar* app_system_query_gtk_application_id (AppSystem* self, gulong window);
gchar* app_system_query_atom_string (AppSystem* self, gulong xid, GdkAtom atom);
static gchar* app_system_query_atom_string_internal (AppSystem* self, gulong xid, GdkAtom atom, gboolean utf8);
gchar* app_system_query_atom_string_utf8 (AppSystem* self, gulong xid, GdkAtom atom);
static void app_system_finalize (GObject* obj);
static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func);


static void _g_free0_ (gpointer var) {
	var = (g_free (var), NULL);
}


static gboolean __lambda5_ (AppSystem* self) {
	gboolean result = FALSE;
	GError * _inner_error_ = NULL;
	{
		gboolean _tmp0_ = FALSE;
		_tmp0_ = self->priv->invalidated;
		g_rec_mutex_lock (&self->priv->__lock_invalidated);
		{
			self->priv->invalidated = TRUE;
		}
		__finally0:
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = self->priv->invalidated;
			g_rec_mutex_unlock (&self->priv->__lock_invalidated);
		}
		if (G_UNLIKELY (_inner_error_ != NULL)) {
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
			g_clear_error (&_inner_error_);
			return FALSE;
		}
	}
	result = FALSE;
	return result;
}


static gboolean ___lambda5__gsource_func (gpointer self) {
	gboolean result;
	result = __lambda5_ ((AppSystem*) self);
	return result;
}


static void __lambda4_ (AppSystem* self) {
	g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, ___lambda5__gsource_func, g_object_ref (self), g_object_unref);
}


static void ___lambda4__g_app_info_monitor_changed (GAppInfoMonitor* _sender, gpointer self) {
	__lambda4_ ((AppSystem*) self);
}


AppSystem* app_system_construct (GType object_type) {
	AppSystem * self = NULL;
	GHashFunc _tmp0_ = NULL;
	GEqualFunc _tmp1_ = NULL;
	GHashTable* _tmp2_ = NULL;
	GHashTable* _tmp3_ = NULL;
	gchar* _tmp4_ = NULL;
	gchar* _tmp5_ = NULL;
	GHashTable* _tmp6_ = NULL;
	gchar* _tmp7_ = NULL;
	gchar* _tmp8_ = NULL;
	GHashTable* _tmp9_ = NULL;
	gchar* _tmp10_ = NULL;
	gchar* _tmp11_ = NULL;
	GHashTable* _tmp12_ = NULL;
	gchar* _tmp13_ = NULL;
	gchar* _tmp14_ = NULL;
	GHashTable* _tmp15_ = NULL;
	gchar* _tmp16_ = NULL;
	gchar* _tmp17_ = NULL;
	gchar* _tmp18_ = NULL;
	gchar* _tmp19_ = NULL;
	gchar* _tmp20_ = NULL;
	gchar* _tmp21_ = NULL;
	gchar* _tmp22_ = NULL;
	gchar* _tmp23_ = NULL;
	gchar* _tmp24_ = NULL;
	gchar* _tmp25_ = NULL;
	gchar* _tmp26_ = NULL;
	gchar* _tmp27_ = NULL;
	gchar* _tmp28_ = NULL;
	gchar* _tmp29_ = NULL;
	gchar** _tmp30_ = NULL;
	GAppInfoMonitor* _tmp31_ = NULL;
	GAppInfoMonitor* _tmp32_ = NULL;
	self = (AppSystem*) g_object_new (object_type, NULL);
	_tmp0_ = g_str_hash;
	_tmp1_ = g_str_equal;
	_tmp2_ = g_hash_table_new_full (_tmp0_, _tmp1_, _g_free0_, _g_free0_);
	_g_hash_table_unref0 (self->priv->simpletons);
	self->priv->simpletons = _tmp2_;
	_tmp3_ = self->priv->simpletons;
	_tmp4_ = g_strdup ("google-chrome-stable");
	_tmp5_ = g_strdup ("google-chrome");
	g_hash_table_insert (_tmp3_, _tmp4_, _tmp5_);
	_tmp6_ = self->priv->simpletons;
	_tmp7_ = g_strdup ("calibre-gui");
	_tmp8_ = g_strdup ("calibre");
	g_hash_table_insert (_tmp6_, _tmp7_, _tmp8_);
	_tmp9_ = self->priv->simpletons;
	_tmp10_ = g_strdup ("code - oss");
	_tmp11_ = g_strdup ("vscode-oss");
	g_hash_table_insert (_tmp9_, _tmp10_, _tmp11_);
	_tmp12_ = self->priv->simpletons;
	_tmp13_ = g_strdup ("code");
	_tmp14_ = g_strdup ("vscode");
	g_hash_table_insert (_tmp12_, _tmp13_, _tmp14_);
	_tmp15_ = self->priv->simpletons;
	_tmp16_ = g_strdup ("psppire");
	_tmp17_ = g_strdup ("pspp");
	g_hash_table_insert (_tmp15_, _tmp16_, _tmp17_);
	_tmp18_ = g_strdup ("atom");
	_tmp19_ = g_strdup ("calibre-gui");
	_tmp20_ = g_strdup ("dia");
	_tmp21_ = g_strdup ("freeorion");
	_tmp22_ = g_strdup ("fbreader");
	_tmp23_ = g_strdup ("google-chrome");
	_tmp24_ = g_strdup ("hexchat");
	_tmp25_ = g_strdup ("pale moon");
	_tmp26_ = g_strdup ("spotify");
	_tmp27_ = g_strdup ("steam");
	_tmp28_ = g_strdup ("telegram");
	_tmp29_ = g_strdup ("zim");
	_tmp30_ = g_new0 (gchar*, 12 + 1);
	_tmp30_[0] = _tmp18_;
	_tmp30_[1] = _tmp19_;
	_tmp30_[2] = _tmp20_;
	_tmp30_[3] = _tmp21_;
	_tmp30_[4] = _tmp22_;
	_tmp30_[5] = _tmp23_;
	_tmp30_[6] = _tmp24_;
	_tmp30_[7] = _tmp25_;
	_tmp30_[8] = _tmp26_;
	_tmp30_[9] = _tmp27_;
	_tmp30_[10] = _tmp28_;
	_tmp30_[11] = _tmp29_;
	self->priv->derpers = (_vala_array_free (self->priv->derpers, self->priv->derpers_length1, (GDestroyNotify) g_free), NULL);
	self->priv->derpers = _tmp30_;
	self->priv->derpers_length1 = 12;
	self->priv->_derpers_size_ = self->priv->derpers_length1;
	_tmp31_ = g_app_info_monitor_get ();
	_g_object_unref0 (self->priv->monitor);
	self->priv->monitor = _tmp31_;
	_tmp32_ = self->priv->monitor;
	g_signal_connect_object (_tmp32_, "changed", (GCallback) ___lambda4__g_app_info_monitor_changed, self, 0);
	app_system_reload_ids (self);
	return self;
}


AppSystem* app_system_new (void) {
	return app_system_construct (TYPE_APP_SYSTEM);
}


/**
     * Determine if the app is forbidden from changing its icon through
     * the icon-changed signal
     */
static gboolean _vala_string_array_contains (gchar** stack, int stack_length, gchar* needle) {
	int i;
	for (i = 0; i < stack_length; i++) {
		if (g_strcmp0 (stack[i], needle) == 0) {
			return TRUE;
		}
	}
	return FALSE;
}


gboolean app_system_has_derpy_icon (AppSystem* self, WnckWindow* window) {
	gboolean result = FALSE;
	gchar* iname = NULL;
	WnckWindow* _tmp0_ = NULL;
	const gchar* _tmp1_ = NULL;
	gchar* _tmp2_ = NULL;
	const gchar* _tmp3_ = NULL;
	const gchar* _tmp4_ = NULL;
	gchar* _tmp5_ = NULL;
	const gchar* _tmp6_ = NULL;
	gchar** _tmp7_ = NULL;
	gint _tmp7__length1 = 0;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = window;
	_tmp1_ = wnck_window_get_class_instance_name (_tmp0_);
	_tmp2_ = g_strdup (_tmp1_);
	iname = _tmp2_;
	_tmp3_ = iname;
	if (_tmp3_ == NULL) {
		result = FALSE;
		_g_free0 (iname);
		return result;
	}
	_tmp4_ = iname;
	_tmp5_ = g_utf8_strdown (_tmp4_, (gssize) -1);
	_g_free0 (iname);
	iname = _tmp5_;
	_tmp6_ = iname;
	_tmp7_ = self->priv->derpers;
	_tmp7__length1 = self->priv->derpers_length1;
	if (_vala_string_array_contains (_tmp7_, _tmp7__length1, _tmp6_)) {
		result = TRUE;
		_g_free0 (iname);
		return result;
	}
	result = FALSE;
	_g_free0 (iname);
	return result;
}


/**
     * We lazily check if at some point we became invalidated. In most cases
     * a package operation or similar modified a desktop file, i.e. making it
     * available or unavailable.
     *
     * Instead of immediately reloading the appsystem we wait until something
     * is actually requested again, check if we're invalidated, reload and then
     * set us validated again.
     */
static void app_system_check_invalidated (AppSystem* self) {
	gboolean _tmp0_ = FALSE;
	GError * _inner_error_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->invalidated;
	if (_tmp0_) {
		{
			gboolean _tmp1_ = FALSE;
			_tmp1_ = self->priv->invalidated;
			g_rec_mutex_lock (&self->priv->__lock_invalidated);
			{
				app_system_reload_ids (self);
				self->priv->invalidated = FALSE;
			}
			__finally1:
			{
				gboolean _tmp2_ = FALSE;
				_tmp2_ = self->priv->invalidated;
				g_rec_mutex_unlock (&self->priv->__lock_invalidated);
			}
			if (G_UNLIKELY (_inner_error_ != NULL)) {
				g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
				g_clear_error (&_inner_error_);
				return;
			}
		}
	}
}


/**
     * Reload and cache all the desktop IDS
     */
static void _g_object_unref0_ (gpointer var) {
	(var == NULL) ? NULL : (var = (g_object_unref (var), NULL));
}


static gpointer _g_object_ref0 (gpointer self) {
	return self ? g_object_ref (self) : NULL;
}


static void _g_list_free__g_object_unref0_ (GList* self) {
	g_list_foreach (self, (GFunc) _g_object_unref0_, NULL);
	g_list_free (self);
}


static void app_system_reload_ids (AppSystem* self) {
	GHashFunc _tmp0_ = NULL;
	GEqualFunc _tmp1_ = NULL;
	GHashTable* _tmp2_ = NULL;
	GHashFunc _tmp3_ = NULL;
	GEqualFunc _tmp4_ = NULL;
	GHashTable* _tmp5_ = NULL;
	GHashFunc _tmp6_ = NULL;
	GEqualFunc _tmp7_ = NULL;
	GHashTable* _tmp8_ = NULL;
	GList* _tmp9_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = g_str_hash;
	_tmp1_ = g_str_equal;
	_tmp2_ = g_hash_table_new_full (_tmp0_, _tmp1_, _g_free0_, _g_free0_);
	_g_hash_table_unref0 (self->priv->startupids);
	self->priv->startupids = _tmp2_;
	_tmp3_ = g_str_hash;
	_tmp4_ = g_str_equal;
	_tmp5_ = g_hash_table_new_full (_tmp3_, _tmp4_, _g_free0_, _g_object_unref0_);
	_g_hash_table_unref0 (self->priv->desktops);
	self->priv->desktops = _tmp5_;
	_tmp6_ = g_str_hash;
	_tmp7_ = g_str_equal;
	_tmp8_ = g_hash_table_new_full (_tmp6_, _tmp7_, _g_free0_, _g_free0_);
	_g_hash_table_unref0 (self->priv->exec_cache);
	self->priv->exec_cache = _tmp8_;
	_tmp9_ = g_app_info_get_all ();
	{
		GList* appinfo_collection = NULL;
		GList* appinfo_it = NULL;
		appinfo_collection = _tmp9_;
		for (appinfo_it = appinfo_collection; appinfo_it != NULL; appinfo_it = appinfo_it->next) {
			GAppInfo* _tmp10_ = NULL;
			GAppInfo* appinfo = NULL;
			_tmp10_ = _g_object_ref0 ((GAppInfo*) appinfo_it->data);
			appinfo = _tmp10_;
			{
				GDesktopAppInfo* dinfo = NULL;
				GAppInfo* _tmp11_ = NULL;
				GDesktopAppInfo* _tmp12_ = NULL;
				GDesktopAppInfo* _tmp13_ = NULL;
				const gchar* _tmp14_ = NULL;
				GHashTable* _tmp22_ = NULL;
				GDesktopAppInfo* _tmp23_ = NULL;
				const gchar* _tmp24_ = NULL;
				gchar* _tmp25_ = NULL;
				GDesktopAppInfo* _tmp26_ = NULL;
				GDesktopAppInfo* _tmp27_ = NULL;
				gchar* try_exec = NULL;
				GDesktopAppInfo* _tmp28_ = NULL;
				const gchar* _tmp29_ = NULL;
				gchar* _tmp30_ = NULL;
				const gchar* _tmp31_ = NULL;
				const gchar* _tmp35_ = NULL;
				const gchar* _tmp36_ = NULL;
				gchar* _tmp37_ = NULL;
				const gchar* _tmp38_ = NULL;
				gchar* _tmp39_ = NULL;
				GHashTable* _tmp40_ = NULL;
				const gchar* _tmp41_ = NULL;
				gchar* _tmp42_ = NULL;
				GDesktopAppInfo* _tmp43_ = NULL;
				const gchar* _tmp44_ = NULL;
				gchar* _tmp45_ = NULL;
				_tmp11_ = appinfo;
				_tmp12_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_TYPE (_tmp11_, G_TYPE_DESKTOP_APP_INFO) ? ((GDesktopAppInfo*) _tmp11_) : NULL);
				dinfo = _tmp12_;
				_tmp13_ = dinfo;
				_tmp14_ = g_desktop_app_info_get_startup_wm_class (_tmp13_);
				if (_tmp14_ != NULL) {
					GHashTable* _tmp15_ = NULL;
					GDesktopAppInfo* _tmp16_ = NULL;
					const gchar* _tmp17_ = NULL;
					gchar* _tmp18_ = NULL;
					GDesktopAppInfo* _tmp19_ = NULL;
					const gchar* _tmp20_ = NULL;
					gchar* _tmp21_ = NULL;
					_tmp15_ = self->priv->startupids;
					_tmp16_ = dinfo;
					_tmp17_ = g_desktop_app_info_get_startup_wm_class (_tmp16_);
					_tmp18_ = g_utf8_strdown (_tmp17_, (gssize) -1);
					_tmp19_ = dinfo;
					_tmp20_ = g_app_info_get_id ((GAppInfo*) _tmp19_);
					_tmp21_ = g_strdup (_tmp20_);
					g_hash_table_insert (_tmp15_, _tmp18_, _tmp21_);
				}
				_tmp22_ = self->priv->desktops;
				_tmp23_ = dinfo;
				_tmp24_ = g_app_info_get_id ((GAppInfo*) _tmp23_);
				_tmp25_ = g_utf8_strdown (_tmp24_, (gssize) -1);
				_tmp26_ = dinfo;
				_tmp27_ = _g_object_ref0 (_tmp26_);
				g_hash_table_insert (_tmp22_, _tmp25_, _tmp27_);
				_tmp28_ = dinfo;
				_tmp29_ = g_desktop_app_info_get_string (_tmp28_, "TryExec");
				_tmp30_ = g_strdup (_tmp29_);
				try_exec = _tmp30_;
				_tmp31_ = try_exec;
				if (_tmp31_ == NULL) {
					GDesktopAppInfo* _tmp32_ = NULL;
					const gchar* _tmp33_ = NULL;
					gchar* _tmp34_ = NULL;
					_tmp32_ = dinfo;
					_tmp33_ = g_app_info_get_executable ((GAppInfo*) _tmp32_);
					_tmp34_ = g_strdup (_tmp33_);
					_g_free0 (try_exec);
					try_exec = _tmp34_;
				}
				_tmp35_ = try_exec;
				if (_tmp35_ == NULL) {
					_g_free0 (try_exec);
					_g_object_unref0 (dinfo);
					_g_object_unref0 (appinfo);
					continue;
				}
				_tmp36_ = try_exec;
				_tmp37_ = g_uri_unescape_string (_tmp36_, NULL);
				_g_free0 (try_exec);
				try_exec = _tmp37_;
				_tmp38_ = try_exec;
				_tmp39_ = g_path_get_basename (_tmp38_);
				_g_free0 (try_exec);
				try_exec = _tmp39_;
				_tmp40_ = self->priv->exec_cache;
				_tmp41_ = try_exec;
				_tmp42_ = g_strdup (_tmp41_);
				_tmp43_ = dinfo;
				_tmp44_ = g_app_info_get_id ((GAppInfo*) _tmp43_);
				_tmp45_ = g_strdup (_tmp44_);
				g_hash_table_insert (_tmp40_, _tmp42_, _tmp45_);
				_g_free0 (try_exec);
				_g_object_unref0 (dinfo);
				_g_object_unref0 (appinfo);
			}
		}
		__g_list_free__g_object_unref0_0 (appinfo_collection);
	}
}


/**
     * Attempt to gain the DesktopAppInfo relating to a given window
     */
GDesktopAppInfo* app_system_query_window (AppSystem* self, WnckWindow* window) {
	GDesktopAppInfo* result = NULL;
	gulong xid = 0UL;
	WnckWindow* _tmp0_ = NULL;
	gulong _tmp1_ = 0UL;
	WnckWindow* _tmp2_ = NULL;
	gchar* cls_name = NULL;
	WnckWindow* _tmp3_ = NULL;
	const gchar* _tmp4_ = NULL;
	gchar* _tmp5_ = NULL;
	gchar* grp_name = NULL;
	WnckWindow* _tmp6_ = NULL;
	const gchar* _tmp7_ = NULL;
	gchar* _tmp8_ = NULL;
	gchar** checks = NULL;
	const gchar* _tmp9_ = NULL;
	gchar* _tmp10_ = NULL;
	const gchar* _tmp11_ = NULL;
	gchar* _tmp12_ = NULL;
	gchar** _tmp13_ = NULL;
	gint checks_length1 = 0;
	gint _checks_size_ = 0;
	gchar** _tmp14_ = NULL;
	gint _tmp14__length1 = 0;
	gchar* gtk_id = NULL;
	gulong _tmp42_ = 0UL;
	gchar* _tmp43_ = NULL;
	const gchar* _tmp44_ = NULL;
	gboolean _tmp56_ = FALSE;
	const gchar* _tmp57_ = NULL;
	gchar** _tmp98_ = NULL;
	gint _tmp98__length1 = 0;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = window;
	_tmp1_ = wnck_window_get_xid (_tmp0_);
	xid = _tmp1_;
	_tmp2_ = window;
	if (_tmp2_ == NULL) {
		result = NULL;
		return result;
	}
	_tmp3_ = window;
	_tmp4_ = wnck_window_get_class_instance_name (_tmp3_);
	_tmp5_ = g_strdup (_tmp4_);
	cls_name = _tmp5_;
	_tmp6_ = window;
	_tmp7_ = wnck_window_get_class_group_name (_tmp6_);
	_tmp8_ = g_strdup (_tmp7_);
	grp_name = _tmp8_;
	app_system_check_invalidated (self);
	_tmp9_ = cls_name;
	_tmp10_ = g_strdup (_tmp9_);
	_tmp11_ = grp_name;
	_tmp12_ = g_strdup (_tmp11_);
	_tmp13_ = g_new0 (gchar*, 2 + 1);
	_tmp13_[0] = _tmp10_;
	_tmp13_[1] = _tmp12_;
	checks = _tmp13_;
	checks_length1 = 2;
	_checks_size_ = checks_length1;
	_tmp14_ = checks;
	_tmp14__length1 = checks_length1;
	{
		gchar** check_collection = NULL;
		gint check_collection_length1 = 0;
		gint _check_collection_size_ = 0;
		gint check_it = 0;
		check_collection = _tmp14_;
		check_collection_length1 = _tmp14__length1;
		for (check_it = 0; check_it < _tmp14__length1; check_it = check_it + 1) {
			gchar* _tmp15_ = NULL;
			gchar* check = NULL;
			_tmp15_ = g_strdup (check_collection[check_it]);
			check = _tmp15_;
			{
				const gchar* _tmp16_ = NULL;
				const gchar* _tmp17_ = NULL;
				gchar* _tmp18_ = NULL;
				GHashTable* _tmp19_ = NULL;
				const gchar* _tmp20_ = NULL;
				gboolean _tmp21_ = FALSE;
				gchar* dname = NULL;
				const gchar* _tmp33_ = NULL;
				gchar* _tmp34_ = NULL;
				GHashTable* _tmp35_ = NULL;
				const gchar* _tmp36_ = NULL;
				gboolean _tmp37_ = FALSE;
				_tmp16_ = check;
				if (_tmp16_ == NULL) {
					_g_free0 (check);
					continue;
				}
				_tmp17_ = check;
				_tmp18_ = g_utf8_strdown (_tmp17_, (gssize) -1);
				_g_free0 (check);
				check = _tmp18_;
				_tmp19_ = self->priv->startupids;
				_tmp20_ = check;
				_tmp21_ = g_hash_table_contains (_tmp19_, _tmp20_);
				if (_tmp21_) {
					gchar* dname = NULL;
					GHashTable* _tmp22_ = NULL;
					const gchar* _tmp23_ = NULL;
					gconstpointer _tmp24_ = NULL;
					gchar* _tmp25_ = NULL;
					GHashTable* _tmp26_ = NULL;
					const gchar* _tmp27_ = NULL;
					gboolean _tmp28_ = FALSE;
					_tmp22_ = self->priv->startupids;
					_tmp23_ = check;
					_tmp24_ = g_hash_table_lookup (_tmp22_, _tmp23_);
					_tmp25_ = g_utf8_strdown ((const gchar*) _tmp24_, (gssize) -1);
					dname = _tmp25_;
					_tmp26_ = self->priv->desktops;
					_tmp27_ = dname;
					_tmp28_ = g_hash_table_contains (_tmp26_, _tmp27_);
					if (_tmp28_) {
						GHashTable* _tmp29_ = NULL;
						const gchar* _tmp30_ = NULL;
						gconstpointer _tmp31_ = NULL;
						GDesktopAppInfo* _tmp32_ = NULL;
						_tmp29_ = self->priv->desktops;
						_tmp30_ = dname;
						_tmp31_ = g_hash_table_lookup (_tmp29_, _tmp30_);
						_tmp32_ = _g_object_ref0 ((GDesktopAppInfo*) _tmp31_);
						result = _tmp32_;
						_g_free0 (dname);
						_g_free0 (check);
						checks = (_vala_array_free (checks, checks_length1, (GDestroyNotify) g_free), NULL);
						_g_free0 (grp_name);
						_g_free0 (cls_name);
						return result;
					}
					_g_free0 (dname);
				}
				_tmp33_ = check;
				_tmp34_ = g_strconcat (_tmp33_, ".desktop", NULL);
				dname = _tmp34_;
				_tmp35_ = self->priv->desktops;
				_tmp36_ = dname;
				_tmp37_ = g_hash_table_contains (_tmp35_, _tmp36_);
				if (_tmp37_) {
					GHashTable* _tmp38_ = NULL;
					const gchar* _tmp39_ = NULL;
					gconstpointer _tmp40_ = NULL;
					GDesktopAppInfo* _tmp41_ = NULL;
					_tmp38_ = self->priv->desktops;
					_tmp39_ = dname;
					_tmp40_ = g_hash_table_lookup (_tmp38_, _tmp39_);
					_tmp41_ = _g_object_ref0 ((GDesktopAppInfo*) _tmp40_);
					result = _tmp41_;
					_g_free0 (dname);
					_g_free0 (check);
					checks = (_vala_array_free (checks, checks_length1, (GDestroyNotify) g_free), NULL);
					_g_free0 (grp_name);
					_g_free0 (cls_name);
					return result;
				}
				_g_free0 (dname);
				_g_free0 (check);
			}
		}
	}
	_tmp42_ = xid;
	_tmp43_ = app_system_query_gtk_application_id (self, _tmp42_);
	gtk_id = _tmp43_;
	_tmp44_ = gtk_id;
	if (_tmp44_ != NULL) {
		const gchar* _tmp45_ = NULL;
		gchar* _tmp46_ = NULL;
		gchar* _tmp47_ = NULL;
		gchar* _tmp48_ = NULL;
		GHashTable* _tmp49_ = NULL;
		const gchar* _tmp50_ = NULL;
		gboolean _tmp51_ = FALSE;
		_tmp45_ = gtk_id;
		_tmp46_ = g_utf8_strdown (_tmp45_, (gssize) -1);
		_tmp47_ = _tmp46_;
		_tmp48_ = g_strconcat (_tmp47_, ".desktop", NULL);
		_g_free0 (gtk_id);
		gtk_id = _tmp48_;
		_g_free0 (_tmp47_);
		_tmp49_ = self->priv->desktops;
		_tmp50_ = gtk_id;
		_tmp51_ = g_hash_table_contains (_tmp49_, _tmp50_);
		if (_tmp51_) {
			GHashTable* _tmp52_ = NULL;
			const gchar* _tmp53_ = NULL;
			gconstpointer _tmp54_ = NULL;
			GDesktopAppInfo* _tmp55_ = NULL;
			_tmp52_ = self->priv->desktops;
			_tmp53_ = gtk_id;
			_tmp54_ = g_hash_table_lookup (_tmp52_, _tmp53_);
			_tmp55_ = _g_object_ref0 ((GDesktopAppInfo*) _tmp54_);
			result = _tmp55_;
			_g_free0 (gtk_id);
			checks = (_vala_array_free (checks, checks_length1, (GDestroyNotify) g_free), NULL);
			_g_free0 (grp_name);
			_g_free0 (cls_name);
			return result;
		}
	}
	_tmp57_ = grp_name;
	if (_tmp57_ != NULL) {
		GHashTable* _tmp58_ = NULL;
		const gchar* _tmp59_ = NULL;
		gchar* _tmp60_ = NULL;
		gchar* _tmp61_ = NULL;
		gboolean _tmp62_ = FALSE;
		_tmp58_ = self->priv->simpletons;
		_tmp59_ = grp_name;
		_tmp60_ = g_utf8_strdown (_tmp59_, (gssize) -1);
		_tmp61_ = _tmp60_;
		_tmp62_ = g_hash_table_contains (_tmp58_, _tmp61_);
		_tmp56_ = _tmp62_;
		_g_free0 (_tmp61_);
	} else {
		_tmp56_ = FALSE;
	}
	if (_tmp56_) {
		gchar* dname = NULL;
		GHashTable* _tmp63_ = NULL;
		const gchar* _tmp64_ = NULL;
		gchar* _tmp65_ = NULL;
		gchar* _tmp66_ = NULL;
		gconstpointer _tmp67_ = NULL;
		gchar* _tmp68_ = NULL;
		gchar* _tmp69_ = NULL;
		GHashTable* _tmp70_ = NULL;
		const gchar* _tmp71_ = NULL;
		gboolean _tmp72_ = FALSE;
		_tmp63_ = self->priv->simpletons;
		_tmp64_ = grp_name;
		_tmp65_ = g_utf8_strdown (_tmp64_, (gssize) -1);
		_tmp66_ = _tmp65_;
		_tmp67_ = g_hash_table_lookup (_tmp63_, _tmp66_);
		_tmp68_ = g_strconcat ((const gchar*) _tmp67_, ".desktop", NULL);
		_tmp69_ = _tmp68_;
		_g_free0 (_tmp66_);
		dname = _tmp69_;
		_tmp70_ = self->priv->desktops;
		_tmp71_ = dname;
		_tmp72_ = g_hash_table_contains (_tmp70_, _tmp71_);
		if (_tmp72_) {
			GHashTable* _tmp73_ = NULL;
			const gchar* _tmp74_ = NULL;
			gconstpointer _tmp75_ = NULL;
			GDesktopAppInfo* _tmp76_ = NULL;
			_tmp73_ = self->priv->desktops;
			_tmp74_ = dname;
			_tmp75_ = g_hash_table_lookup (_tmp73_, _tmp74_);
			_tmp76_ = _g_object_ref0 ((GDesktopAppInfo*) _tmp75_);
			result = _tmp76_;
			_g_free0 (dname);
			_g_free0 (gtk_id);
			checks = (_vala_array_free (checks, checks_length1, (GDestroyNotify) g_free), NULL);
			_g_free0 (grp_name);
			_g_free0 (cls_name);
			return result;
		}
		_g_free0 (dname);
	} else {
		gboolean _tmp77_ = FALSE;
		const gchar* _tmp78_ = NULL;
		_tmp78_ = cls_name;
		if (_tmp78_ != NULL) {
			GHashTable* _tmp79_ = NULL;
			const gchar* _tmp80_ = NULL;
			gchar* _tmp81_ = NULL;
			gchar* _tmp82_ = NULL;
			gboolean _tmp83_ = FALSE;
			_tmp79_ = self->priv->simpletons;
			_tmp80_ = cls_name;
			_tmp81_ = g_utf8_strdown (_tmp80_, (gssize) -1);
			_tmp82_ = _tmp81_;
			_tmp83_ = g_hash_table_contains (_tmp79_, _tmp82_);
			_tmp77_ = _tmp83_;
			_g_free0 (_tmp82_);
		} else {
			_tmp77_ = FALSE;
		}
		if (_tmp77_) {
			gchar* dname = NULL;
			GHashTable* _tmp84_ = NULL;
			const gchar* _tmp85_ = NULL;
			gchar* _tmp86_ = NULL;
			gchar* _tmp87_ = NULL;
			gconstpointer _tmp88_ = NULL;
			gchar* _tmp89_ = NULL;
			gchar* _tmp90_ = NULL;
			GHashTable* _tmp91_ = NULL;
			const gchar* _tmp92_ = NULL;
			gboolean _tmp93_ = FALSE;
			_tmp84_ = self->priv->simpletons;
			_tmp85_ = cls_name;
			_tmp86_ = g_utf8_strdown (_tmp85_, (gssize) -1);
			_tmp87_ = _tmp86_;
			_tmp88_ = g_hash_table_lookup (_tmp84_, _tmp87_);
			_tmp89_ = g_strconcat ((const gchar*) _tmp88_, ".desktop", NULL);
			_tmp90_ = _tmp89_;
			_g_free0 (_tmp87_);
			dname = _tmp90_;
			_tmp91_ = self->priv->desktops;
			_tmp92_ = dname;
			_tmp93_ = g_hash_table_contains (_tmp91_, _tmp92_);
			if (_tmp93_) {
				GHashTable* _tmp94_ = NULL;
				const gchar* _tmp95_ = NULL;
				gconstpointer _tmp96_ = NULL;
				GDesktopAppInfo* _tmp97_ = NULL;
				_tmp94_ = self->priv->desktops;
				_tmp95_ = dname;
				_tmp96_ = g_hash_table_lookup (_tmp94_, _tmp95_);
				_tmp97_ = _g_object_ref0 ((GDesktopAppInfo*) _tmp96_);
				result = _tmp97_;
				_g_free0 (dname);
				_g_free0 (gtk_id);
				checks = (_vala_array_free (checks, checks_length1, (GDestroyNotify) g_free), NULL);
				_g_free0 (grp_name);
				_g_free0 (cls_name);
				return result;
			}
			_g_free0 (dname);
		}
	}
	_tmp98_ = checks;
	_tmp98__length1 = checks_length1;
	{
		gchar** check_collection = NULL;
		gint check_collection_length1 = 0;
		gint _check_collection_size_ = 0;
		gint check_it = 0;
		check_collection = _tmp98_;
		check_collection_length1 = _tmp98__length1;
		for (check_it = 0; check_it < _tmp98__length1; check_it = check_it + 1) {
			gchar* _tmp99_ = NULL;
			gchar* check = NULL;
			_tmp99_ = g_strdup (check_collection[check_it]);
			check = _tmp99_;
			{
				const gchar* _tmp100_ = NULL;
				const gchar* _tmp101_ = NULL;
				gchar* _tmp102_ = NULL;
				gchar* id = NULL;
				GHashTable* _tmp103_ = NULL;
				const gchar* _tmp104_ = NULL;
				gconstpointer _tmp105_ = NULL;
				gchar* _tmp106_ = NULL;
				const gchar* _tmp107_ = NULL;
				GDesktopAppInfo* a = NULL;
				GHashTable* _tmp108_ = NULL;
				const gchar* _tmp109_ = NULL;
				gconstpointer _tmp110_ = NULL;
				GDesktopAppInfo* _tmp111_ = NULL;
				_tmp100_ = check;
				if (_tmp100_ == NULL) {
					_g_free0 (check);
					continue;
				}
				_tmp101_ = check;
				_tmp102_ = g_utf8_strdown (_tmp101_, (gssize) -1);
				_g_free0 (check);
				check = _tmp102_;
				_tmp103_ = self->priv->exec_cache;
				_tmp104_ = check;
				_tmp105_ = g_hash_table_lookup (_tmp103_, _tmp104_);
				_tmp106_ = g_strdup ((const gchar*) _tmp105_);
				id = _tmp106_;
				_tmp107_ = id;
				if (_tmp107_ == NULL) {
					_g_free0 (id);
					_g_free0 (check);
					continue;
				}
				_tmp108_ = self->priv->desktops;
				_tmp109_ = id;
				_tmp110_ = g_hash_table_lookup (_tmp108_, _tmp109_);
				a = (GDesktopAppInfo*) _tmp110_;
				_tmp111_ = a;
				if (_tmp111_ != NULL) {
					GDesktopAppInfo* _tmp112_ = NULL;
					GDesktopAppInfo* _tmp113_ = NULL;
					_tmp112_ = a;
					_tmp113_ = _g_object_ref0 (_tmp112_);
					result = _tmp113_;
					_g_free0 (id);
					_g_free0 (check);
					_g_free0 (gtk_id);
					checks = (_vala_array_free (checks, checks_length1, (GDestroyNotify) g_free), NULL);
					_g_free0 (grp_name);
					_g_free0 (cls_name);
					return result;
				}
				_g_free0 (id);
				_g_free0 (check);
			}
		}
	}
	result = NULL;
	_g_free0 (gtk_id);
	checks = (_vala_array_free (checks, checks_length1, (GDestroyNotify) g_free), NULL);
	_g_free0 (grp_name);
	_g_free0 (cls_name);
	return result;
}


/**
     * Return a plain STRING value for the given window id
     */
gchar* app_system_query_atom_string (AppSystem* self, gulong xid, GdkAtom atom) {
	gchar* result = NULL;
	gulong _tmp0_ = 0UL;
	GdkAtom _tmp1_ = 0U;
	gchar* _tmp2_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = xid;
	_tmp1_ = atom;
	_tmp2_ = app_system_query_atom_string_internal (self, _tmp0_, _tmp1_, FALSE);
	result = _tmp2_;
	return result;
}


/**
     * Return a UTF8_STRING value for the given window id
     */
gchar* app_system_query_atom_string_utf8 (AppSystem* self, gulong xid, GdkAtom atom) {
	gchar* result = NULL;
	gulong _tmp0_ = 0UL;
	GdkAtom _tmp1_ = 0U;
	gchar* _tmp2_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = xid;
	_tmp1_ = atom;
	_tmp2_ = app_system_query_atom_string_internal (self, _tmp0_, _tmp1_, TRUE);
	result = _tmp2_;
	return result;
}


static gchar* app_system_query_atom_string_internal (AppSystem* self, gulong xid, GdkAtom atom, gboolean utf8) {
	gchar* result = NULL;
	guint8* data = NULL;
	gint data_length1 = 0;
	gint _data_size_ = 0;
	GdkAtom a_type = 0U;
	gint a_f = 0;
	GdkDisplay* display = NULL;
	GdkDisplay* _tmp0_ = NULL;
	GdkDisplay* _tmp1_ = NULL;
	GdkAtom req_type = 0U;
	gboolean _tmp2_ = FALSE;
	GdkWindow* foreign = NULL;
	GdkDisplay* _tmp5_ = NULL;
	gulong _tmp6_ = 0UL;
	GdkWindow* _tmp7_ = NULL;
	GdkWindow* _tmp8_ = NULL;
	GdkWindow* _tmp9_ = NULL;
	GdkWindow* _tmp10_ = NULL;
	GdkAtom _tmp11_ = 0U;
	GdkAtom _tmp12_ = 0U;
	GdkAtom _tmp13_ = 0U;
	gint _tmp14_ = 0;
	guint8* _tmp15_ = NULL;
	gint _tmp16_ = 0;
	const gchar* _tmp17_ = NULL;
	guint8* _tmp18_ = NULL;
	gint _tmp18__length1 = 0;
	gchar* _tmp20_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	data = NULL;
	data_length1 = 0;
	_data_size_ = data_length1;
	_tmp0_ = gdk_display_get_default ();
	_tmp1_ = _g_object_ref0 (_tmp0_);
	display = _tmp1_;
	_tmp2_ = utf8;
	if (_tmp2_) {
		GdkAtom _tmp3_ = 0U;
		_tmp3_ = gdk_atom_intern ("UTF8_STRING", FALSE);
		req_type = _tmp3_;
	} else {
		GdkAtom _tmp4_ = 0U;
		_tmp4_ = gdk_atom_intern ("STRING", FALSE);
		req_type = _tmp4_;
	}
	_tmp5_ = display;
	_tmp6_ = xid;
	_tmp7_ = gdk_x11_window_foreign_new_for_display (_tmp5_, (Window) _tmp6_);
	_tmp8_ = _g_object_ref0 (_tmp7_);
	foreign = _tmp8_;
	_tmp9_ = foreign;
	if (_tmp9_ == NULL) {
		result = NULL;
		_g_object_unref0 (foreign);
		_g_object_unref0 (display);
		data = (g_free (data), NULL);
		return result;
	}
	_tmp10_ = foreign;
	_tmp11_ = atom;
	_tmp12_ = req_type;
	gdk_property_get (_tmp10_, _tmp11_, _tmp12_, (gulong) 0, (gulong) G_MAXLONG, 0, &_tmp13_, &_tmp14_, &_tmp16_, &_tmp15_);
	a_type = _tmp13_;
	a_f = _tmp14_;
	data = (g_free (data), NULL);
	data = _tmp15_;
	data_length1 = _tmp16_;
	_data_size_ = data_length1;
	_tmp18_ = data;
	_tmp18__length1 = data_length1;
	if (_tmp18_ != NULL) {
		guint8* _tmp19_ = NULL;
		gint _tmp19__length1 = 0;
		_tmp19_ = data;
		_tmp19__length1 = data_length1;
		_tmp17_ = (const gchar*) _tmp19_;
	} else {
		_tmp17_ = NULL;
	}
	_tmp20_ = g_strdup (_tmp17_);
	result = _tmp20_;
	_g_object_unref0 (foreign);
	_g_object_unref0 (display);
	data = (g_free (data), NULL);
	return result;
}


/**
     * Obtain the GtkApplication id for a given window
     */
gchar* app_system_query_gtk_application_id (AppSystem* self, gulong window) {
	gchar* result = NULL;
	gulong _tmp0_ = 0UL;
	GdkAtom _tmp1_ = 0U;
	gchar* _tmp2_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = window;
	_tmp1_ = gdk_atom_intern ("_GTK_APPLICATION_ID", FALSE);
	_tmp2_ = app_system_query_atom_string_utf8 (self, _tmp0_, _tmp1_);
	result = _tmp2_;
	return result;
}


static void app_system_class_init (AppSystemClass * klass) {
	app_system_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (AppSystemPrivate));
	G_OBJECT_CLASS (klass)->finalize = app_system_finalize;
}


static void app_system_instance_init (AppSystem * self) {
	self->priv = APP_SYSTEM_GET_PRIVATE (self);
	self->priv->startupids = NULL;
	self->priv->simpletons = NULL;
	self->priv->desktops = NULL;
	self->priv->exec_cache = NULL;
	self->priv->monitor = NULL;
	g_rec_mutex_init (&self->priv->__lock_invalidated);
	self->priv->invalidated = FALSE;
}


static void app_system_finalize (GObject* obj) {
	AppSystem * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_APP_SYSTEM, AppSystem);
	_g_hash_table_unref0 (self->priv->startupids);
	_g_hash_table_unref0 (self->priv->simpletons);
	_g_hash_table_unref0 (self->priv->desktops);
	_g_hash_table_unref0 (self->priv->exec_cache);
	_g_object_unref0 (self->priv->monitor);
	self->priv->derpers = (_vala_array_free (self->priv->derpers, self->priv->derpers_length1, (GDestroyNotify) g_free), NULL);
	g_rec_mutex_clear (&self->priv->__lock_invalidated);
	G_OBJECT_CLASS (app_system_parent_class)->finalize (obj);
}


GType app_system_get_type (void) {
	return app_system_type_id;
}


GType app_system_register_type (GTypeModule * module) {
	static const GTypeInfo g_define_type_info = { sizeof (AppSystemClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) app_system_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (AppSystem), 0, (GInstanceInitFunc) app_system_instance_init, NULL };
	app_system_type_id = g_type_module_register_type (module, G_TYPE_OBJECT, "AppSystem", &g_define_type_info, 0);
	return app_system_type_id;
}


static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	if ((array != NULL) && (destroy_func != NULL)) {
		int i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}


static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}



