/* Main.c generated by valac 0.56.18-dirty, the Vala compiler
 * generated from Main.vala, do not modify */

/**/
/*  Copyright (C) 2017 Adam Bieńkowski*/
/**/
/*  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 3 of the License, or*/
/*  (at your option) any later version.*/
/**/
/*  This program is distributed in the hope that it will be useful,*/
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of*/
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the*/
/*  GNU General Public License for more details.*/
/**/
/*  You should have received a copy of the GNU General Public License*/
/*  along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
/**/

#include "gala-pip.h"
#include <gee.h>
#include <glib-object.h>
#include "gala.h"
#include <glib.h>
#include <mtk/mtk.h>
#include <meta/display.h>
#include <meta/meta-plugin.h>
#include <gio/gio.h>
#include <meta/prefs.h>
#include <meta/window.h>
#include <clutter/clutter.h>
#include <meta/keybindings.h>
#include <meta/meta-window-actor.h>
#include <graphene-gobject.h>
#include <float.h>
#include <math.h>
#include <meta/compositor-mutter.h>
#include <stdlib.h>
#include <string.h>

#define GALA_PLUGINS_PIP_PLUGIN_MIN_SELECTION_SIZE 30
#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

enum  {
	GALA_PLUGINS_PIP_PLUGIN_0_PROPERTY,
	GALA_PLUGINS_PIP_PLUGIN_NUM_PROPERTIES
};
static GParamSpec* gala_plugins_pip_plugin_properties[GALA_PLUGINS_PIP_PLUGIN_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef struct _Block1Data Block1Data;
typedef struct _Block2Data Block2Data;
typedef struct _Block3Data Block3Data;
#define _g_free0(var) (var = (g_free (var), NULL))

struct _GalaPluginsPIPPluginPrivate {
	GeeArrayList* windows;
	GalaWindowManager* wm;
	GalaPluginsPIPSelectionArea* selection_area;
};

struct _Block1Data {
	int _ref_count_;
	GalaPluginsPIPPlugin* self;
	MetaWindowActor* selected;
	gint x;
	gint y;
};

struct _Block2Data {
	int _ref_count_;
	GalaPluginsPIPPlugin* self;
	MetaWindowActor* active;
};

struct _Block3Data {
	int _ref_count_;
	GalaPluginsPIPPlugin* self;
	GalaPluginsPIPPopupWindow* popup_window;
};

static gint GalaPluginsPIPPlugin_private_offset;
static gpointer gala_plugins_pip_plugin_parent_class = NULL;

static inline gboolean gala_plugins_pip_plugin_meta_rectangle_contains (MtkRectangle* rect,
                                                          gint x,
                                                          gint y);
static void gala_plugins_pip_plugin_real_initialize (GalaPlugin* base,
                                              GalaWindowManager* wm);
static void gala_plugins_pip_plugin_on_initiate (GalaPluginsPIPPlugin* self,
                                          MetaDisplay* display,
                                          MetaWindow* window,
                                          ClutterKeyEvent* event,
                                          MetaKeyBinding* binding);
static void _gala_plugins_pip_plugin_on_initiate_meta_key_handler_func (MetaDisplay* display,
                                                                 MetaWindow* window,
                                                                 const ClutterKeyEvent* event,
                                                                 MetaKeyBinding* binding,
                                                                 gpointer self);
static void gala_plugins_pip_plugin_real_destroy (GalaPlugin* base);
static void gala_plugins_pip_plugin_clear_selection_area (GalaPluginsPIPPlugin* self);
static void gala_plugins_pip_plugin_untrack_window (GalaPluginsPIPPlugin* self,
                                             GalaPluginsPIPPopupWindow* popup_window);
static void gala_plugins_pip_plugin_on_selection_actor_selected (GalaPluginsPIPPlugin* self,
                                                          gint x,
                                                          gint y);
static void _gala_plugins_pip_plugin_on_selection_actor_selected_gala_plugins_pip_selection_area_selected (GalaPluginsPIPSelectionArea* _sender,
                                                                                                    gint x,
                                                                                                    gint y,
                                                                                                    gpointer self);
static void gala_plugins_pip_plugin_on_selection_actor_captured (GalaPluginsPIPPlugin* self,
                                                          gint x,
                                                          gint y,
                                                          gint width,
                                                          gint height);
static void _gala_plugins_pip_plugin_on_selection_actor_captured_gala_plugins_pip_selection_area_captured (GalaPluginsPIPSelectionArea* _sender,
                                                                                                    gint x,
                                                                                                    gint y,
                                                                                                    gint width,
                                                                                                    gint height,
                                                                                                    gpointer self);
static void _gala_plugins_pip_plugin_clear_selection_area_gala_plugins_pip_selection_area_closed (GalaPluginsPIPSelectionArea* _sender,
                                                                                           gpointer self);
static void gala_plugins_pip_plugin_select_window_at (GalaPluginsPIPPlugin* self,
                                               gint x,
                                               gint y);
static MetaWindowActor* gala_plugins_pip_plugin_get_active_window_actor (GalaPluginsPIPPlugin* self);
static void gala_plugins_pip_plugin_on_popup_window_show (GalaPluginsPIPPlugin* self,
                                                   ClutterActor* popup_window);
static void _gala_plugins_pip_plugin_on_popup_window_show_clutter_actor_show (ClutterActor* _sender,
                                                                       gpointer self);
static void gala_plugins_pip_plugin_on_popup_window_hide (GalaPluginsPIPPlugin* self,
                                                   ClutterActor* popup_window);
static void _gala_plugins_pip_plugin_on_popup_window_hide_clutter_actor_hide (ClutterActor* _sender,
                                                                       gpointer self);
static void gala_plugins_pip_plugin_add_window (GalaPluginsPIPPlugin* self,
                                         GalaPluginsPIPPopupWindow* popup_window);
static MetaWindowActor* gala_plugins_pip_plugin_get_window_actor_at (GalaPluginsPIPPlugin* self,
                                                              gint x,
                                                              gint y);
static Block1Data* block1_data_ref (Block1Data* _data1_);
static void block1_data_unref (void * _userdata_);
static void __lambda6_ (Block1Data* _data1_,
                 MetaWindowActor* actor);
static void ___lambda6__gfunc (gconstpointer data,
                        gpointer self);
static Block2Data* block2_data_ref (Block2Data* _data2_);
static void block2_data_unref (void * _userdata_);
static void __lambda8_ (Block2Data* _data2_,
                 MetaWindowActor* actor);
static void ___lambda8__gfunc (gconstpointer data,
                        gpointer self);
static Block3Data* block3_data_ref (Block3Data* _data3_);
static void block3_data_unref (void * _userdata_);
static void __lambda7_ (Block3Data* _data3_);
static void gala_plugins_pip_plugin_remove_window (GalaPluginsPIPPlugin* self,
                                            GalaPluginsPIPPopupWindow* popup_window);
static void ___lambda7__gala_plugins_pip_popup_window_closed (GalaPluginsPIPPopupWindow* _sender,
                                                       gpointer self);
static GObject * gala_plugins_pip_plugin_constructor (GType type,
                                               guint n_construct_properties,
                                               GObjectConstructParam * construct_properties);
static void gala_plugins_pip_plugin_finalize (GObject * obj);
static GType gala_plugins_pip_plugin_get_type_once (void);

static inline gpointer
gala_plugins_pip_plugin_get_instance_private (GalaPluginsPIPPlugin* self)
{
	return G_STRUCT_MEMBER_P (self, GalaPluginsPIPPlugin_private_offset);
}

static inline gboolean
gala_plugins_pip_plugin_meta_rectangle_contains (MtkRectangle* rect,
                                                 gint x,
                                                 gint y)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	MtkRectangle _tmp3_;
	gboolean result;
	g_return_val_if_fail (rect != NULL, FALSE);
	_tmp3_ = *rect;
	if (x >= _tmp3_.x) {
		MtkRectangle _tmp4_;
		MtkRectangle _tmp5_;
		_tmp4_ = *rect;
		_tmp5_ = *rect;
		_tmp2_ = x < (_tmp4_.x + _tmp5_.width);
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		MtkRectangle _tmp6_;
		_tmp6_ = *rect;
		_tmp1_ = y >= _tmp6_.y;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		MtkRectangle _tmp7_;
		MtkRectangle _tmp8_;
		_tmp7_ = *rect;
		_tmp8_ = *rect;
		_tmp0_ = y < (_tmp7_.y + _tmp8_.height);
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

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

static void
_gala_plugins_pip_plugin_on_initiate_meta_key_handler_func (MetaDisplay* display,
                                                            MetaWindow* window,
                                                            const ClutterKeyEvent* event,
                                                            MetaKeyBinding* binding,
                                                            gpointer self)
{
	gala_plugins_pip_plugin_on_initiate ((GalaPluginsPIPPlugin*) self, display, window, event, binding);
}

static void
gala_plugins_pip_plugin_real_initialize (GalaPlugin* base,
                                         GalaWindowManager* wm)
{
	GalaPluginsPIPPlugin * self;
	GalaWindowManager* _tmp0_;
	MetaDisplay* display = NULL;
	MetaDisplay* _tmp1_;
	MetaDisplay* _tmp2_;
	GSettings* settings = NULL;
	GSettings* _tmp3_;
	self = (GalaPluginsPIPPlugin*) base;
	g_return_if_fail (wm != NULL);
	_tmp0_ = _g_object_ref0 (wm);
	_g_object_unref0 (self->priv->wm);
	self->priv->wm = _tmp0_;
	_tmp1_ = meta_plugin_get_display ((MetaPlugin*) wm);
	_tmp2_ = _g_object_ref0 (_tmp1_);
	display = _tmp2_;
	_tmp3_ = g_settings_new ("io.elementary.desktop.wm.keybindings");
	settings = _tmp3_;
	meta_display_add_keybinding (display, "pip", settings, META_KEY_BINDING_IGNORE_AUTOREPEAT, _gala_plugins_pip_plugin_on_initiate_meta_key_handler_func, g_object_ref (self), g_object_unref);
	_g_object_unref0 (settings);
	_g_object_unref0 (display);
}

static void
gala_plugins_pip_plugin_real_destroy (GalaPlugin* base)
{
	GalaPluginsPIPPlugin * self;
	GeeArrayList* _tmp9_;
	self = (GalaPluginsPIPPlugin*) base;
	gala_plugins_pip_plugin_clear_selection_area (self);
	{
		GeeArrayList* _popup_window_list = NULL;
		GeeArrayList* _tmp0_;
		gint _popup_window_size = 0;
		GeeArrayList* _tmp1_;
		gint _tmp2_;
		gint _tmp3_;
		gint _popup_window_index = 0;
		_tmp0_ = self->priv->windows;
		_popup_window_list = _tmp0_;
		_tmp1_ = _popup_window_list;
		_tmp2_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp1_);
		_tmp3_ = _tmp2_;
		_popup_window_size = _tmp3_;
		_popup_window_index = -1;
		while (TRUE) {
			gint _tmp4_;
			gint _tmp5_;
			GalaPluginsPIPPopupWindow* popup_window = NULL;
			GeeArrayList* _tmp6_;
			gpointer _tmp7_;
			GalaPluginsPIPPopupWindow* _tmp8_;
			_popup_window_index = _popup_window_index + 1;
			_tmp4_ = _popup_window_index;
			_tmp5_ = _popup_window_size;
			if (!(_tmp4_ < _tmp5_)) {
				break;
			}
			_tmp6_ = _popup_window_list;
			_tmp7_ = gee_abstract_list_get ((GeeAbstractList*) _tmp6_, _popup_window_index);
			popup_window = (GalaPluginsPIPPopupWindow*) _tmp7_;
			_tmp8_ = popup_window;
			gala_plugins_pip_plugin_untrack_window (self, _tmp8_);
			_g_object_unref0 (popup_window);
		}
	}
	_tmp9_ = self->priv->windows;
	gee_abstract_collection_clear ((GeeAbstractCollection*) _tmp9_);
}

static void
_gala_plugins_pip_plugin_on_selection_actor_selected_gala_plugins_pip_selection_area_selected (GalaPluginsPIPSelectionArea* _sender,
                                                                                               gint x,
                                                                                               gint y,
                                                                                               gpointer self)
{
	gala_plugins_pip_plugin_on_selection_actor_selected ((GalaPluginsPIPPlugin*) self, x, y);
}

static void
_gala_plugins_pip_plugin_on_selection_actor_captured_gala_plugins_pip_selection_area_captured (GalaPluginsPIPSelectionArea* _sender,
                                                                                               gint x,
                                                                                               gint y,
                                                                                               gint width,
                                                                                               gint height,
                                                                                               gpointer self)
{
	gala_plugins_pip_plugin_on_selection_actor_captured ((GalaPluginsPIPPlugin*) self, x, y, width, height);
}

static void
_gala_plugins_pip_plugin_clear_selection_area_gala_plugins_pip_selection_area_closed (GalaPluginsPIPSelectionArea* _sender,
                                                                                      gpointer self)
{
	gala_plugins_pip_plugin_clear_selection_area ((GalaPluginsPIPPlugin*) self);
}

static void
gala_plugins_pip_plugin_on_initiate (GalaPluginsPIPPlugin* self,
                                     MetaDisplay* display,
                                     MetaWindow* window,
                                     ClutterKeyEvent* event,
                                     MetaKeyBinding* binding)
{
	GalaWindowManager* _tmp0_;
	GalaPluginsPIPSelectionArea* _tmp1_;
	GalaPluginsPIPSelectionArea* _tmp2_;
	GalaPluginsPIPSelectionArea* _tmp3_;
	GalaPluginsPIPSelectionArea* _tmp4_;
	GalaPluginsPIPSelectionArea* _tmp5_;
	GalaWindowManager* _tmp6_;
	ClutterActor* _tmp7_;
	ClutterActor* _tmp8_;
	GalaPluginsPIPSelectionArea* _tmp9_;
	GalaPluginsPIPSelectionArea* _tmp10_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (display != NULL);
	g_return_if_fail (binding != NULL);
	_tmp0_ = self->priv->wm;
	_tmp1_ = gala_plugins_pip_selection_area_new (_tmp0_);
	g_object_ref_sink (_tmp1_);
	_g_object_unref0 (self->priv->selection_area);
	self->priv->selection_area = _tmp1_;
	_tmp2_ = self->priv->selection_area;
	g_signal_connect_object (_tmp2_, "selected", (GCallback) _gala_plugins_pip_plugin_on_selection_actor_selected_gala_plugins_pip_selection_area_selected, self, 0);
	_tmp3_ = self->priv->selection_area;
	g_signal_connect_object (_tmp3_, "captured", (GCallback) _gala_plugins_pip_plugin_on_selection_actor_captured_gala_plugins_pip_selection_area_captured, self, 0);
	_tmp4_ = self->priv->selection_area;
	g_signal_connect_object (_tmp4_, "closed", (GCallback) _gala_plugins_pip_plugin_clear_selection_area_gala_plugins_pip_selection_area_closed, self, 0);
	_tmp5_ = self->priv->selection_area;
	gala_plugin_track_actor ((GalaPlugin*) self, (ClutterActor*) _tmp5_);
	_tmp6_ = self->priv->wm;
	_tmp7_ = gala_window_manager_get_ui_group (_tmp6_);
	_tmp8_ = _tmp7_;
	_tmp9_ = self->priv->selection_area;
	clutter_actor_add_child (_tmp8_, (ClutterActor*) _tmp9_);
	_tmp10_ = self->priv->selection_area;
	gala_plugins_pip_selection_area_start_selection (_tmp10_);
}

static void
gala_plugins_pip_plugin_on_selection_actor_selected (GalaPluginsPIPPlugin* self,
                                                     gint x,
                                                     gint y)
{
	g_return_if_fail (self != NULL);
	gala_plugins_pip_plugin_clear_selection_area (self);
	gala_plugins_pip_plugin_select_window_at (self, x, y);
}

static void
_gala_plugins_pip_plugin_on_popup_window_show_clutter_actor_show (ClutterActor* _sender,
                                                                  gpointer self)
{
	gala_plugins_pip_plugin_on_popup_window_show ((GalaPluginsPIPPlugin*) self, _sender);
}

static void
_gala_plugins_pip_plugin_on_popup_window_hide_clutter_actor_hide (ClutterActor* _sender,
                                                                  gpointer self)
{
	gala_plugins_pip_plugin_on_popup_window_hide ((GalaPluginsPIPPlugin*) self, _sender);
}

static void
gala_plugins_pip_plugin_on_selection_actor_captured (GalaPluginsPIPPlugin* self,
                                                     gint x,
                                                     gint y,
                                                     gint width,
                                                     gint height)
{
	MetaWindowActor* active = NULL;
	MetaWindowActor* _tmp0_;
	MetaWindowActor* _tmp1_;
	MetaWindow* window = NULL;
	MetaWindowActor* _tmp2_;
	MetaWindow* _tmp3_;
	MetaWindow* _tmp4_;
	MetaWindow* _tmp5_;
	MtkRectangle buffer_rect = {0};
	MetaWindow* _tmp6_;
	MtkRectangle _tmp7_ = {0};
	MtkRectangle frame_rect = {0};
	MetaWindow* _tmp8_;
	MtkRectangle _tmp9_ = {0};
	MtkRectangle mtk_rect = {0};
	MtkRectangle _tmp10_ = {0};
	MtkRectangle intersection = {0};
	MtkRectangle _tmp11_;
	MtkRectangle _tmp12_ = {0};
	gint x_offset = 0;
	MtkRectangle _tmp13_;
	MtkRectangle _tmp14_;
	gint y_offset = 0;
	MtkRectangle _tmp15_;
	MtkRectangle _tmp16_;
	graphene_rect_t rect = {0};
	MtkRectangle _tmp17_;
	MtkRectangle _tmp18_;
	MtkRectangle _tmp19_;
	MtkRectangle _tmp20_;
	MtkRectangle _tmp21_;
	MtkRectangle _tmp22_;
	graphene_rect_t _tmp23_ = {0};
	gboolean _tmp24_ = FALSE;
	GalaPluginsPIPPopupWindow* popup_window = NULL;
	GalaWindowManager* _tmp25_;
	MetaDisplay* _tmp26_;
	MetaWindowActor* _tmp27_;
	GalaPluginsPIPPopupWindow* _tmp28_;
	GalaPluginsPIPPopupWindow* _tmp29_;
	graphene_rect_t _tmp30_;
	GalaPluginsPIPPopupWindow* _tmp31_;
	GalaPluginsPIPPopupWindow* _tmp32_;
	GalaPluginsPIPPopupWindow* _tmp33_;
	g_return_if_fail (self != NULL);
	gala_plugins_pip_plugin_clear_selection_area (self);
	_tmp0_ = gala_plugins_pip_plugin_get_active_window_actor (self);
	active = _tmp0_;
	_tmp1_ = active;
	if (_tmp1_ == NULL) {
		_g_object_unref0 (active);
		return;
	}
	_tmp2_ = active;
	_tmp3_ = meta_window_actor_get_meta_window (_tmp2_);
	_tmp4_ = _tmp3_;
	_tmp5_ = _g_object_ref0 (_tmp4_);
	window = _tmp5_;
	_tmp6_ = window;
	meta_window_get_buffer_rect (_tmp6_, &_tmp7_);
	buffer_rect = _tmp7_;
	_tmp8_ = window;
	meta_window_get_frame_rect (_tmp8_, &_tmp9_);
	frame_rect = _tmp9_;
	_tmp10_.x = x;
	_tmp10_.y = y;
	_tmp10_.width = width;
	_tmp10_.height = height;
	mtk_rect = _tmp10_;
	_tmp11_ = frame_rect;
	mtk_rectangle_intersect (&mtk_rect, &_tmp11_, &_tmp12_);
	intersection = _tmp12_;
	_tmp13_ = buffer_rect;
	_tmp14_ = frame_rect;
	x_offset = _tmp13_.x - _tmp14_.x;
	_tmp15_ = buffer_rect;
	_tmp16_ = frame_rect;
	y_offset = _tmp15_.y - _tmp16_.y;
	_tmp17_ = intersection;
	_tmp18_ = buffer_rect;
	_tmp19_ = intersection;
	_tmp20_ = buffer_rect;
	_tmp21_ = intersection;
	_tmp22_ = intersection;
	_tmp23_.origin = (graphene_point_t) {(gfloat) ((_tmp17_.x - _tmp18_.x) + x_offset), (gfloat) ((_tmp19_.y - _tmp20_.y) + y_offset)};
	_tmp23_.size = (graphene_size_t) {(gfloat) _tmp21_.width, (gfloat) _tmp22_.height};
	rect = _tmp23_;
	if (graphene_rect_get_width (&rect) < ((gfloat) GALA_PLUGINS_PIP_PLUGIN_MIN_SELECTION_SIZE)) {
		_tmp24_ = TRUE;
	} else {
		_tmp24_ = graphene_rect_get_height (&rect) < ((gfloat) GALA_PLUGINS_PIP_PLUGIN_MIN_SELECTION_SIZE);
	}
	if (_tmp24_) {
		gala_plugins_pip_plugin_select_window_at (self, x, y);
		_g_object_unref0 (window);
		_g_object_unref0 (active);
		return;
	}
	_tmp25_ = self->priv->wm;
	_tmp26_ = meta_plugin_get_display ((MetaPlugin*) _tmp25_);
	_tmp27_ = active;
	_tmp28_ = gala_plugins_pip_popup_window_new (_tmp26_, _tmp27_);
	g_object_ref_sink (_tmp28_);
	popup_window = _tmp28_;
	_tmp29_ = popup_window;
	_tmp30_ = rect;
	gala_plugins_pip_popup_window_set_container_clip (_tmp29_, &_tmp30_);
	_tmp31_ = popup_window;
	g_signal_connect_object ((ClutterActor*) _tmp31_, "show", (GCallback) _gala_plugins_pip_plugin_on_popup_window_show_clutter_actor_show, self, 0);
	_tmp32_ = popup_window;
	g_signal_connect_object ((ClutterActor*) _tmp32_, "hide", (GCallback) _gala_plugins_pip_plugin_on_popup_window_hide_clutter_actor_hide, self, 0);
	_tmp33_ = popup_window;
	gala_plugins_pip_plugin_add_window (self, _tmp33_);
	_g_object_unref0 (popup_window);
	_g_object_unref0 (window);
	_g_object_unref0 (active);
}

static void
gala_plugins_pip_plugin_on_popup_window_show (GalaPluginsPIPPlugin* self,
                                              ClutterActor* popup_window)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (popup_window != NULL);
	gala_plugin_track_actor ((GalaPlugin*) self, popup_window);
	gala_plugin_update_region ((GalaPlugin*) self);
}

static void
gala_plugins_pip_plugin_on_popup_window_hide (GalaPluginsPIPPlugin* self,
                                              ClutterActor* popup_window)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (popup_window != NULL);
	gala_plugin_untrack_actor ((GalaPlugin*) self, popup_window);
	gala_plugin_update_region ((GalaPlugin*) self);
}

static void
gala_plugins_pip_plugin_select_window_at (GalaPluginsPIPPlugin* self,
                                          gint x,
                                          gint y)
{
	MetaWindowActor* selected = NULL;
	MetaWindowActor* _tmp0_;
	MetaWindowActor* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = gala_plugins_pip_plugin_get_window_actor_at (self, x, y);
	selected = _tmp0_;
	_tmp1_ = selected;
	if (_tmp1_ != NULL) {
		GalaPluginsPIPPopupWindow* popup_window = NULL;
		GalaWindowManager* _tmp2_;
		MetaDisplay* _tmp3_;
		MetaWindowActor* _tmp4_;
		GalaPluginsPIPPopupWindow* _tmp5_;
		GalaPluginsPIPPopupWindow* _tmp6_;
		GalaPluginsPIPPopupWindow* _tmp7_;
		GalaPluginsPIPPopupWindow* _tmp8_;
		_tmp2_ = self->priv->wm;
		_tmp3_ = meta_plugin_get_display ((MetaPlugin*) _tmp2_);
		_tmp4_ = selected;
		_tmp5_ = gala_plugins_pip_popup_window_new (_tmp3_, _tmp4_);
		g_object_ref_sink (_tmp5_);
		popup_window = _tmp5_;
		_tmp6_ = popup_window;
		g_signal_connect_object ((ClutterActor*) _tmp6_, "show", (GCallback) _gala_plugins_pip_plugin_on_popup_window_show_clutter_actor_show, self, 0);
		_tmp7_ = popup_window;
		g_signal_connect_object ((ClutterActor*) _tmp7_, "hide", (GCallback) _gala_plugins_pip_plugin_on_popup_window_hide_clutter_actor_hide, self, 0);
		_tmp8_ = popup_window;
		gala_plugins_pip_plugin_add_window (self, _tmp8_);
		_g_object_unref0 (popup_window);
	}
	_g_object_unref0 (selected);
}

static void
gala_plugins_pip_plugin_clear_selection_area (GalaPluginsPIPPlugin* self)
{
	GalaPluginsPIPSelectionArea* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->selection_area;
	if (_tmp0_ != NULL) {
		GalaPluginsPIPSelectionArea* _tmp1_;
		GalaPluginsPIPSelectionArea* _tmp2_;
		_tmp1_ = self->priv->selection_area;
		gala_plugin_untrack_actor ((GalaPlugin*) self, (ClutterActor*) _tmp1_);
		gala_plugin_update_region ((GalaPlugin*) self);
		_tmp2_ = self->priv->selection_area;
		clutter_actor_destroy ((ClutterActor*) _tmp2_);
		_g_object_unref0 (self->priv->selection_area);
		self->priv->selection_area = NULL;
	}
}

static Block1Data*
block1_data_ref (Block1Data* _data1_)
{
	g_atomic_int_inc (&_data1_->_ref_count_);
	return _data1_;
}

static void
block1_data_unref (void * _userdata_)
{
	Block1Data* _data1_;
	_data1_ = (Block1Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data1_->_ref_count_)) {
		GalaPluginsPIPPlugin* self;
		self = _data1_->self;
		_g_object_unref0 (self);
		g_slice_free (Block1Data, _data1_);
	}
}

static void
__lambda6_ (Block1Data* _data1_,
            MetaWindowActor* actor)
{
	GalaPluginsPIPPlugin* self;
	MetaWindow* window = NULL;
	MetaWindow* _tmp0_;
	MetaWindow* _tmp1_;
	MtkRectangle rect = {0};
	MetaWindow* _tmp2_;
	MtkRectangle _tmp3_ = {0};
	gboolean _tmp4_ = FALSE;
	gboolean _tmp5_ = FALSE;
	gboolean _tmp6_ = FALSE;
	self = _data1_->self;
	g_return_if_fail (actor != NULL);
	if (_data1_->selected != NULL) {
		return;
	}
	_tmp0_ = meta_window_actor_get_meta_window (actor);
	_tmp1_ = _g_object_ref0 (_tmp0_);
	window = _tmp1_;
	_tmp2_ = window;
	meta_window_get_frame_rect (_tmp2_, &_tmp3_);
	rect = _tmp3_;
	if (!meta_window_actor_is_destroyed (actor)) {
		MetaWindow* _tmp7_;
		_tmp7_ = window;
		_tmp6_ = !meta_window_is_hidden (_tmp7_);
	} else {
		_tmp6_ = FALSE;
	}
	if (_tmp6_) {
		MetaWindow* _tmp8_;
		_tmp8_ = window;
		_tmp5_ = !meta_window_is_skip_taskbar (_tmp8_);
	} else {
		_tmp5_ = FALSE;
	}
	if (_tmp5_) {
		MtkRectangle _tmp9_;
		_tmp9_ = rect;
		_tmp4_ = gala_plugins_pip_plugin_meta_rectangle_contains (&_tmp9_, _data1_->x, _data1_->y);
	} else {
		_tmp4_ = FALSE;
	}
	if (_tmp4_) {
		_data1_->selected = actor;
	}
	_g_object_unref0 (window);
}

static void
___lambda6__gfunc (gconstpointer data,
                   gpointer self)
{
	__lambda6_ (self, (MetaWindowActor*) data);
}

static MetaWindowActor*
gala_plugins_pip_plugin_get_window_actor_at (GalaPluginsPIPPlugin* self,
                                             gint x,
                                             gint y)
{
	Block1Data* _data1_;
	MetaDisplay* display = NULL;
	GalaWindowManager* _tmp0_;
	MetaDisplay* _tmp1_;
	GList* actors = NULL;
	GList* _tmp2_;
	GList* copy = NULL;
	GList* _tmp3_;
	MetaWindowActor* _tmp4_;
	MetaWindowActor* result;
	g_return_val_if_fail (self != NULL, NULL);
	_data1_ = g_slice_new0 (Block1Data);
	_data1_->_ref_count_ = 1;
	_data1_->self = g_object_ref (self);
	_data1_->x = x;
	_data1_->y = y;
	_tmp0_ = self->priv->wm;
	_tmp1_ = meta_plugin_get_display ((MetaPlugin*) _tmp0_);
	display = _tmp1_;
	_tmp2_ = meta_get_window_actors (display);
	actors = _tmp2_;
	_tmp3_ = g_list_copy (actors);
	copy = _tmp3_;
	copy = g_list_reverse (copy);
	_data1_->selected = NULL;
	g_list_foreach (copy, ___lambda6__gfunc, _data1_);
	_tmp4_ = _g_object_ref0 (_data1_->selected);
	result = _tmp4_;
	(copy == NULL) ? NULL : (copy = (g_list_free (copy), NULL));
	block1_data_unref (_data1_);
	_data1_ = NULL;
	return result;
}

static Block2Data*
block2_data_ref (Block2Data* _data2_)
{
	g_atomic_int_inc (&_data2_->_ref_count_);
	return _data2_;
}

static void
block2_data_unref (void * _userdata_)
{
	Block2Data* _data2_;
	_data2_ = (Block2Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data2_->_ref_count_)) {
		GalaPluginsPIPPlugin* self;
		self = _data2_->self;
		_g_object_unref0 (self);
		g_slice_free (Block2Data, _data2_);
	}
}

static void
__lambda8_ (Block2Data* _data2_,
            MetaWindowActor* actor)
{
	GalaPluginsPIPPlugin* self;
	MetaWindow* window = NULL;
	MetaWindow* _tmp0_;
	MetaWindow* _tmp1_;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	gboolean _tmp4_ = FALSE;
	self = _data2_->self;
	g_return_if_fail (actor != NULL);
	if (_data2_->active != NULL) {
		return;
	}
	_tmp0_ = meta_window_actor_get_meta_window (actor);
	_tmp1_ = _g_object_ref0 (_tmp0_);
	window = _tmp1_;
	if (!meta_window_actor_is_destroyed (actor)) {
		MetaWindow* _tmp5_;
		_tmp5_ = window;
		_tmp4_ = !meta_window_is_hidden (_tmp5_);
	} else {
		_tmp4_ = FALSE;
	}
	if (_tmp4_) {
		MetaWindow* _tmp6_;
		_tmp6_ = window;
		_tmp3_ = !meta_window_is_skip_taskbar (_tmp6_);
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		MetaWindow* _tmp7_;
		_tmp7_ = window;
		_tmp2_ = meta_window_has_focus (_tmp7_);
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		_data2_->active = actor;
	}
	_g_object_unref0 (window);
}

static void
___lambda8__gfunc (gconstpointer data,
                   gpointer self)
{
	__lambda8_ (self, (MetaWindowActor*) data);
}

static MetaWindowActor*
gala_plugins_pip_plugin_get_active_window_actor (GalaPluginsPIPPlugin* self)
{
	Block2Data* _data2_;
	MetaDisplay* display = NULL;
	GalaWindowManager* _tmp0_;
	MetaDisplay* _tmp1_;
	GList* actors = NULL;
	GList* _tmp2_;
	GList* copy = NULL;
	GList* _tmp3_;
	MetaWindowActor* _tmp4_;
	MetaWindowActor* result;
	g_return_val_if_fail (self != NULL, NULL);
	_data2_ = g_slice_new0 (Block2Data);
	_data2_->_ref_count_ = 1;
	_data2_->self = g_object_ref (self);
	_tmp0_ = self->priv->wm;
	_tmp1_ = meta_plugin_get_display ((MetaPlugin*) _tmp0_);
	display = _tmp1_;
	_tmp2_ = meta_get_window_actors (display);
	actors = _tmp2_;
	_tmp3_ = g_list_copy (actors);
	copy = _tmp3_;
	copy = g_list_reverse (copy);
	_data2_->active = NULL;
	g_list_foreach (actors, ___lambda8__gfunc, _data2_);
	_tmp4_ = _g_object_ref0 (_data2_->active);
	result = _tmp4_;
	(copy == NULL) ? NULL : (copy = (g_list_free (copy), NULL));
	block2_data_unref (_data2_);
	_data2_ = NULL;
	return result;
}

static Block3Data*
block3_data_ref (Block3Data* _data3_)
{
	g_atomic_int_inc (&_data3_->_ref_count_);
	return _data3_;
}

static void
block3_data_unref (void * _userdata_)
{
	Block3Data* _data3_;
	_data3_ = (Block3Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data3_->_ref_count_)) {
		GalaPluginsPIPPlugin* self;
		self = _data3_->self;
		_g_object_unref0 (_data3_->popup_window);
		_g_object_unref0 (self);
		g_slice_free (Block3Data, _data3_);
	}
}

static void
__lambda7_ (Block3Data* _data3_)
{
	GalaPluginsPIPPlugin* self;
	self = _data3_->self;
	gala_plugins_pip_plugin_remove_window (self, _data3_->popup_window);
}

static void
___lambda7__gala_plugins_pip_popup_window_closed (GalaPluginsPIPPopupWindow* _sender,
                                                  gpointer self)
{
	__lambda7_ (self);
}

static void
gala_plugins_pip_plugin_add_window (GalaPluginsPIPPlugin* self,
                                    GalaPluginsPIPPopupWindow* popup_window)
{
	Block3Data* _data3_;
	GalaPluginsPIPPopupWindow* _tmp0_;
	GeeArrayList* _tmp1_;
	GalaWindowManager* _tmp2_;
	ClutterActor* _tmp3_;
	ClutterActor* _tmp4_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (popup_window != NULL);
	_data3_ = g_slice_new0 (Block3Data);
	_data3_->_ref_count_ = 1;
	_data3_->self = g_object_ref (self);
	_tmp0_ = _g_object_ref0 (popup_window);
	_g_object_unref0 (_data3_->popup_window);
	_data3_->popup_window = _tmp0_;
	g_signal_connect_data (_data3_->popup_window, "closed", (GCallback) ___lambda7__gala_plugins_pip_popup_window_closed, block3_data_ref (_data3_), (GClosureNotify) block3_data_unref, 0);
	_tmp1_ = self->priv->windows;
	gee_abstract_collection_add ((GeeAbstractCollection*) _tmp1_, _data3_->popup_window);
	_tmp2_ = self->priv->wm;
	_tmp3_ = gala_window_manager_get_ui_group (_tmp2_);
	_tmp4_ = _tmp3_;
	clutter_actor_add_child (_tmp4_, (ClutterActor*) _data3_->popup_window);
	block3_data_unref (_data3_);
	_data3_ = NULL;
}

static void
gala_plugins_pip_plugin_remove_window (GalaPluginsPIPPlugin* self,
                                       GalaPluginsPIPPopupWindow* popup_window)
{
	GeeArrayList* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (popup_window != NULL);
	_tmp0_ = self->priv->windows;
	gee_abstract_collection_remove ((GeeAbstractCollection*) _tmp0_, popup_window);
	gala_plugins_pip_plugin_untrack_window (self, popup_window);
}

static void
gala_plugins_pip_plugin_untrack_window (GalaPluginsPIPPlugin* self,
                                        GalaPluginsPIPPopupWindow* popup_window)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (popup_window != NULL);
	gala_plugin_untrack_actor ((GalaPlugin*) self, (ClutterActor*) popup_window);
	gala_plugin_update_region ((GalaPlugin*) self);
	clutter_actor_destroy ((ClutterActor*) popup_window);
}

GalaPluginsPIPPlugin*
gala_plugins_pip_plugin_construct (GType object_type)
{
	GalaPluginsPIPPlugin * self = NULL;
	self = (GalaPluginsPIPPlugin*) gala_plugin_construct (object_type);
	return self;
}

GalaPluginsPIPPlugin*
gala_plugins_pip_plugin_new (void)
{
	return gala_plugins_pip_plugin_construct (GALA_PLUGINS_PIP_TYPE_PLUGIN);
}

static GObject *
gala_plugins_pip_plugin_constructor (GType type,
                                     guint n_construct_properties,
                                     GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	GalaPluginsPIPPlugin * self;
	GeeArrayList* _tmp0_;
	parent_class = G_OBJECT_CLASS (gala_plugins_pip_plugin_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GALA_PLUGINS_PIP_TYPE_PLUGIN, GalaPluginsPIPPlugin);
	_tmp0_ = gee_array_list_new (GALA_PLUGINS_PIP_TYPE_POPUP_WINDOW, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	_g_object_unref0 (self->priv->windows);
	self->priv->windows = _tmp0_;
	return obj;
}

static void
gala_plugins_pip_plugin_class_init (GalaPluginsPIPPluginClass * klass,
                                    gpointer klass_data)
{
	gala_plugins_pip_plugin_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GalaPluginsPIPPlugin_private_offset);
	((GalaPluginClass *) klass)->initialize = (void (*) (GalaPlugin*, GalaWindowManager*)) gala_plugins_pip_plugin_real_initialize;
	((GalaPluginClass *) klass)->destroy = (void (*) (GalaPlugin*)) gala_plugins_pip_plugin_real_destroy;
	G_OBJECT_CLASS (klass)->constructor = gala_plugins_pip_plugin_constructor;
	G_OBJECT_CLASS (klass)->finalize = gala_plugins_pip_plugin_finalize;
}

static void
gala_plugins_pip_plugin_instance_init (GalaPluginsPIPPlugin * self,
                                       gpointer klass)
{
	self->priv = gala_plugins_pip_plugin_get_instance_private (self);
	self->priv->wm = NULL;
}

static void
gala_plugins_pip_plugin_finalize (GObject * obj)
{
	GalaPluginsPIPPlugin * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GALA_PLUGINS_PIP_TYPE_PLUGIN, GalaPluginsPIPPlugin);
	_g_object_unref0 (self->priv->windows);
	_g_object_unref0 (self->priv->wm);
	_g_object_unref0 (self->priv->selection_area);
	G_OBJECT_CLASS (gala_plugins_pip_plugin_parent_class)->finalize (obj);
}

 G_GNUC_NO_INLINE static GType
gala_plugins_pip_plugin_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GalaPluginsPIPPluginClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gala_plugins_pip_plugin_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GalaPluginsPIPPlugin), 0, (GInstanceInitFunc) gala_plugins_pip_plugin_instance_init, NULL };
	GType gala_plugins_pip_plugin_type_id;
	gala_plugins_pip_plugin_type_id = g_type_register_static (GALA_TYPE_PLUGIN, "GalaPluginsPIPPlugin", &g_define_type_info, 0);
	GalaPluginsPIPPlugin_private_offset = g_type_add_instance_private (gala_plugins_pip_plugin_type_id, sizeof (GalaPluginsPIPPluginPrivate));
	return gala_plugins_pip_plugin_type_id;
}

GType
gala_plugins_pip_plugin_get_type (void)
{
	static gsize gala_plugins_pip_plugin_type_id__once = 0;
	if (g_once_init_enter (&gala_plugins_pip_plugin_type_id__once)) {
		GType gala_plugins_pip_plugin_type_id;
		gala_plugins_pip_plugin_type_id = gala_plugins_pip_plugin_get_type_once ();
		g_once_init_leave (&gala_plugins_pip_plugin_type_id__once, gala_plugins_pip_plugin_type_id);
	}
	return gala_plugins_pip_plugin_type_id__once;
}

void
register_plugin (GalaPluginInfo* result)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	GalaPluginInfo _tmp2_ = {0};
	_tmp0_ = g_strdup ("Popup Window");
	_tmp1_ = g_strdup ("Adam Bieńkowski <donadigos159@gmail.com>");
	memset (&_tmp2_, 0, sizeof (GalaPluginInfo));
	_g_free0 (_tmp2_.name);
	_tmp2_.name = _tmp0_;
	_g_free0 (_tmp2_.author);
	_tmp2_.author = _tmp1_;
	_tmp2_.plugin_type = GALA_PLUGINS_PIP_TYPE_PLUGIN;
	_tmp2_.provides = GALA_PLUGIN_FUNCTION_ADDITION;
	_tmp2_.load_priority = GALA_LOAD_PRIORITY_IMMEDIATE;
	*result = _tmp2_;
	return;
}

