[gnome-calendar/wip/gbsneto/month-cell-subwindow: 3/4] month-view: introduce new overflow popover window



commit eff50668d4f20187a28f628c944070870b33eda6
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Wed Nov 15 02:03:26 2017 -0200

    month-view: introduce new overflow popover window
    
    This ~almost~ implements a perfectly semantic transition (which
    is kinda impossible now).

 data/calendar.gresource.xml    |    1 +
 data/meson.build               |    1 +
 data/theme/gtk-styles.css      |   14 +
 data/ui/month-popover.ui       |   99 +++++
 data/ui/month-view.ui          |   61 ---
 src/meson.build                |    2 +
 src/views/gcal-month-popover.c |  865 ++++++++++++++++++++++++++++++++++++++++
 src/views/gcal-month-popover.h |   50 +++
 src/views/gcal-month-view.c    |  136 ++-----
 9 files changed, 1064 insertions(+), 165 deletions(-)
---
diff --git a/data/calendar.gresource.xml b/data/calendar.gresource.xml
index ccfe72d..1c11d23 100644
--- a/data/calendar.gresource.xml
+++ b/data/calendar.gresource.xml
@@ -8,6 +8,7 @@
     <file alias="edit-dialog.ui" compressed="true" preprocess="xml-stripblanks">ui/edit-dialog.ui</file>
     <file alias="event-widget.ui" compressed="true" preprocess="xml-stripblanks">ui/event-widget.ui</file>
     <file alias="month-cell.ui" compressed="true" preprocess="xml-stripblanks">ui/month-cell.ui</file>
+    <file alias="month-popover.ui" compressed="true" preprocess="xml-stripblanks">ui/month-popover.ui</file>
     <file alias="month-view.ui" compressed="true" preprocess="xml-stripblanks">ui/month-view.ui</file>
     <file alias="multi-choice.ui" compressed="true" preprocess="xml-stripblanks">ui/multi-choice.ui</file>
     <file alias="online-account-row.ui" compressed="true" 
preprocess="xml-stripblanks">ui/online-account-row.ui</file>
diff --git a/data/meson.build b/data/meson.build
index baa50cb..f99ff60 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -55,6 +55,7 @@ resource_data = files(
   'ui/help-overlay.ui',
   'ui/menus.ui',
   'ui/month-cell.ui',
+  'ui/month-popover.ui',
   'ui/month-view.ui',
   'ui/multi-choice.ui',
   'ui/quick-add-popover.ui',
diff --git a/data/theme/gtk-styles.css b/data/theme/gtk-styles.css
index 475589e..4cecb1e 100644
--- a/data/theme/gtk-styles.css
+++ b/data/theme/gtk-styles.css
@@ -465,3 +465,17 @@ monthcell button {
     border-bottom: none;
     border-right: none;
 }
+
+/*
+ * Month popover
+ */
+
+monthpopover { background: transparent; }
+
+monthpopover > box {
+  margin: 4px;
+  border: 1px solid @borders;
+  box-shadow: 0px 0px 2px @wm_shadow;
+  padding: 12px;
+  background: @theme_bg_color;
+}
diff --git a/data/ui/month-popover.ui b/data/ui/month-popover.ui
new file mode 100644
index 0000000..3fc3116
--- /dev/null
+++ b/data/ui/month-popover.ui
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GcalMonthPopover" parent="GtkWindow">
+    <property name="modal">false</property>
+    <property name="opacity">0.0</property>
+    <property name="destroy-with-parent">true</property>
+    <child>
+      <object class="GtkBox">
+        <property name="visible">true</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">12</property>
+
+        <!-- Day label & close button-->
+        <child>
+          <object class="GtkBox">
+            <property name="visible">true</property>
+
+            <child>
+              <object class="GtkLabel" id="day_label">
+                <property name="visible">true</property>
+                <property name="label">12</property>
+                <property name="xalign">0.0</property>
+                <property name="hexpand">true</property>
+                <attributes>
+                  <attribute name="scale" value="2.25" />
+                </attributes>
+              </object>
+            </child>
+
+            <child>
+              <object class="GtkButton">
+                <property name="visible">true</property>
+                <property name="halign">end</property>
+                <property name="valign">start</property>
+                <property name="relief">none</property>
+                <signal name="clicked" handler="close_button_clicked_cb" object="GcalMonthPopover" 
swapped="yes" />
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">true</property>
+                    <property name="icon-name">window-close-symbolic</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+
+          </object>
+        </child>
+
+        <!-- Event list revealer -->
+        <child>
+          <object class="GtkRevealer" id="revealer">
+            <property name="reveal-child">false</property>
+            <property name="transition-duration">200</property>
+            <property name="transition-type">slide-down</property>
+            <property name="visible">true</property>
+            <child>
+              <object class="GtkBox" id="top_box">
+                <property name="orientation">vertical</property>
+                <property name="visible">true</property>
+                <child>
+                  <object class="DzlElasticBin" id="elastic">
+                    <property name="visible">true</property>
+                    <child>
+                      <object class="GtkScrolledWindow" id="scrolled_window">
+                        <property name="hscrollbar-policy">never</property>
+                        <property name="propagate-natural-height">true</property>
+                        <property name="visible">true</property>
+                        <child>
+                          <object class="GtkListBox" id="listbox">
+                            <property name="visible">true</property>
+                            <property name="selection-mode">none</property>
+                            <style>
+                              <class name="background" />
+                            </style>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+
+        <!-- New Event button -->
+        <child>
+          <object class="GtkButton" id="new_event_button">
+            <property name="visible">true</property>
+            <property name="relief">none</property>
+            <property name="label" translatable="yes">New Event…</property>
+            <signal name="clicked" handler="new_event_button_clicked_cb" object="GcalMonthPopover" />
+          </object>
+        </child>
+
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/data/ui/month-view.ui b/data/ui/month-view.ui
index 7b2aa44..afb6977 100644
--- a/data/ui/month-view.ui
+++ b/data/ui/month-view.ui
@@ -142,65 +142,4 @@
       </object>
     </child>
   </template>
-
-  <!-- Overflow popover -->
-  <object class="GtkPopover" id="overflow_popover">
-    <property name="can-focus">false</property>
-    <property name="position">bottom</property>
-    <signal name="drag-motion" handler="cancel_dnd_from_overflow_popover" object="GcalMonthView" 
swapped="no" />
-    <style>
-      <class name="events" />
-    </style>
-
-    <child>
-      <object class="GtkBox">
-        <property name="visible">true</property>
-        <property name="can-focus">false</property>
-        <property name="spacing">6</property>
-        <property name="orientation">vertical</property>
-        <child>
-          <object class="GtkLabel" id="popover_title">
-            <property name="visible">true</property>
-            <property name="can-focus">false</property>
-            <property name="margin-top">6</property>
-            <property name="margin-start">6</property>
-            <property name="margin-end">6</property>
-            <property name="xalign">0.0</property>
-            <style>
-              <class name="sidebar-header" />
-            </style>
-          </object>
-        </child>
-
-        <child>
-          <object class="GtkScrolledWindow">
-            <property name="visible">true</property>
-            <property name="can-focus">false</property>
-            <property name="hscrollbar-policy">never</property>
-            <property name="vscrollbar-policy">automatic</property>
-            <property name="max-content-height">400</property>
-            <property name="propagate-natural-height">true</property>
-            <child>
-              <object class="GtkBox" id="events_box">
-                <property name="visible">true</property>
-                <property name="orientation">vertical</property>
-                <property name="margin-start">2</property>
-                <property name="margin-end">2</property>
-                <property name="spacing">2</property>
-              </object>
-            </child>
-          </object>
-        </child>
-
-        <child>
-          <object class="GtkButton">
-            <property name="visible">true</property>
-            <property name="hexpand">true</property>
-            <property name="label" translatable="yes">Add Event…</property>
-            <signal name="clicked" handler="add_new_event_button_cb" object="GcalMonthView" swapped="no" />
-          </object>
-        </child>
-      </object>
-    </child>
-  </object>
 </interface>
diff --git a/src/meson.build b/src/meson.build
index b5a29e2..3b30e80 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -8,6 +8,7 @@ gcal_deps = [
   libedataserver_dep,
   libevolution_dep,
   libecal_dep,
+  libdazzle_dep,
   libsoup_dep,
   libical_dep,
   glib_dep,
@@ -19,6 +20,7 @@ gcal_deps = [
 
 sources = files(
   'views/gcal-month-cell.c',
+  'views/gcal-month-popover.c',
   'views/gcal-month-view.c',
   'views/gcal-range-tree.c',
   'views/gcal-view.c',
diff --git a/src/views/gcal-month-popover.c b/src/views/gcal-month-popover.c
new file mode 100644
index 0000000..cf0e836
--- /dev/null
+++ b/src/views/gcal-month-popover.c
@@ -0,0 +1,865 @@
+/* gcal-month-popover.c
+ *
+ * Copyright © 2017 Georges Basile Stavracas Neto <georges stavracas gmail 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 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/>.
+ */
+
+#define G_LOG_DOMAIN "GcalMonthPopover"
+
+#include "gcal-event-widget.h"
+#include "gcal-month-popover.h"
+#include "gcal-utils.h"
+
+#include <dazzle.h>
+
+#define RATIO_TO_RELATIVE  1.25
+
+struct _GcalMonthPopover
+{
+  GtkWindow           parent;
+
+  GtkLabel           *day_label;
+  GtkWidget          *listbox;
+  GtkRevealer        *revealer;
+  GtkWidget          *scrolled_window;
+
+  GtkWidget          *relative_to;
+  GtkWindow          *transient_for;
+
+  GcalManager        *manager;
+
+  DzlAnimation       *opacity_animation;
+  DzlAnimation       *position_animation;
+  DzlAnimation       *size_animation;
+
+  gulong              delete_event_handler;
+  gulong              configure_event_handler;
+  gulong              size_allocate_handler;
+
+  /* Positioning flags - range from [0, 1] */
+  gdouble             x_ratio;
+  gdouble             y_ratio;
+
+  GDateTime          *date;
+};
+
+static void          event_activated_cb                          (GcalEventWidget    *event_widget,
+                                                                  GcalMonthPopover   *self);
+
+G_DEFINE_TYPE (GcalMonthPopover, gcal_month_popover, GTK_TYPE_WINDOW)
+
+enum
+{
+  PROP_0,
+  PROP_MANAGER,
+  PROP_RELATIVE_TO,
+  PROP_X,
+  PROP_Y,
+  N_PROPS
+};
+
+enum
+{
+  EVENT_ACTIVATED,
+  LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0, };
+static GParamSpec *properties [N_PROPS] = { NULL, };
+
+
+/*
+ * Auxiliary functions
+ */
+
+static void
+adjust_margin (GcalMonthPopover *self,
+               GdkRectangle     *area)
+{
+  GtkStyleContext *style_context;
+  GtkBorder margin;
+
+  style_context = gtk_widget_get_style_context (gtk_bin_get_child (GTK_BIN (self)));
+  gtk_style_context_get_margin (style_context,
+                                gtk_style_context_get_state (style_context),
+                                &margin);
+
+  area->x -= margin.right;
+  area->y -= margin.top;
+  area->width += margin.right + margin.left;
+  area->height += margin.top + margin.bottom;
+}
+
+static void
+animate_opacity (GcalMonthPopover *self,
+                 gdouble           target)
+{
+  DzlAnimation *animation;
+
+  if (self->opacity_animation)
+    dzl_animation_stop (self->opacity_animation);
+
+  /* Animate the opacity */
+  animation = dzl_object_animate (self,
+                                  DZL_ANIMATION_EASE_IN_OUT_CUBIC,
+                                  250,
+                                  gtk_widget_get_frame_clock (GTK_WIDGET (self)),
+                                  "opacity", target,
+                                  NULL);
+  dzl_set_weak_pointer (&self->opacity_animation, animation);
+}
+
+static void
+animate_position (GcalMonthPopover *self,
+                  gdouble           x_ratio,
+                  gdouble           y_ratio)
+{
+  DzlAnimation *animation;
+
+  if (self->position_animation)
+    dzl_animation_stop (self->position_animation);
+
+  /* Animate the opacity */
+  animation = dzl_object_animate (self,
+                                  DZL_ANIMATION_EASE_IN_OUT_CUBIC,
+                                  200,
+                                  gtk_widget_get_frame_clock (GTK_WIDGET (self)),
+                                  "x", x_ratio,
+                                  "y", y_ratio,
+                                  NULL);
+  dzl_set_weak_pointer (&self->position_animation, animation);
+}
+
+static void
+animate_size (GcalMonthPopover *self,
+              gint              target_width,
+              gint              target_height)
+{
+  DzlAnimation *animation;
+
+  if (self->size_animation)
+    dzl_animation_stop (self->size_animation);
+
+  /* Animate the opacity */
+  animation = dzl_object_animate (self,
+                                  DZL_ANIMATION_EASE_IN_OUT_CUBIC,
+                                  200,
+                                  gtk_widget_get_frame_clock (GTK_WIDGET (self)),
+                                  "width-request", target_width,
+                                  "height-request", target_height,
+                                  NULL);
+  dzl_set_weak_pointer (&self->size_animation, animation);
+}
+
+void
+update_maximum_height (GcalMonthPopover *self)
+{
+  GdkWindow *window;
+  gint clip_height;
+
+  clip_height = 3000;
+  window = gtk_widget_get_window (GTK_WIDGET (self->relative_to));
+
+  if (window)
+    {
+      GdkDisplay *display;
+      GdkMonitor *monitor;
+
+      display = gtk_widget_get_display (GTK_WIDGET (self));
+      monitor = gdk_display_get_monitor_at_window (display, window);
+
+      if (monitor)
+        {
+          GdkRectangle workarea;
+
+          gdk_monitor_get_workarea (monitor, &workarea);
+
+          clip_height = workarea.height / 2;
+        }
+    }
+
+  g_object_set (self->scrolled_window,
+                "max-content-height", clip_height,
+                NULL);
+}
+
+static void
+update_position (GcalMonthPopover *self)
+{
+  GtkAllocation alloc;
+  GtkWidget *toplevel;
+  GdkWindow *window;
+  gint diff_w;
+  gint diff_h;
+  gint x;
+  gint y;
+
+  if (!gtk_widget_get_realized (GTK_WIDGET (self)))
+    return;
+
+  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self->relative_to));
+  window = gtk_widget_get_window (toplevel);
+
+  gtk_widget_get_allocation (GTK_WIDGET (self->relative_to), &alloc);
+
+  alloc.x = 0;
+  alloc.y = 0;
+
+  gtk_widget_translate_coordinates (GTK_WIDGET (self->relative_to), toplevel, 0, 0, &alloc.x, &alloc.y);
+
+  gdk_window_get_position (window, &x, &y);
+  alloc.x += x;
+  alloc.y += y;
+
+  adjust_margin (self, &alloc);
+
+  diff_w = (RATIO_TO_RELATIVE - 1) * alloc.width * (1.0 - self->x_ratio);
+  diff_h = (RATIO_TO_RELATIVE - 1) * alloc.height * (1.0 - self->y_ratio);
+
+  /* Animate the margins, not the (x, y) position) */
+  gtk_widget_set_margin_top (gtk_bin_get_child (GTK_BIN (self)), diff_h / 2);
+
+  if (gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL)
+    gtk_widget_set_margin_end (gtk_bin_get_child (GTK_BIN (self)), diff_w / 2);
+  else
+    gtk_widget_set_margin_start (gtk_bin_get_child (GTK_BIN (self)), diff_w / 2);
+}
+
+static void
+reposition_popover (GcalMonthPopover *self,
+                    gboolean          animate)
+{
+  GtkAllocation alloc;
+  GtkWidget *toplevel;
+  GdkWindow *window;
+  gint diff_w;
+  gint diff_h;
+  gint x;
+  gint y;
+
+  if (!gtk_widget_get_realized (GTK_WIDGET (self)))
+    return;
+
+  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self->relative_to));
+  window = gtk_widget_get_window (toplevel);
+
+  gtk_widget_get_allocation (GTK_WIDGET (self->relative_to), &alloc);
+
+  alloc.x = 0;
+  alloc.y = 0;
+
+  gtk_widget_translate_coordinates (GTK_WIDGET (self->relative_to), toplevel, 0, 0, &alloc.x, &alloc.y);
+
+  gdk_window_get_position (window, &x, &y);
+  alloc.x += x;
+  alloc.y += y;
+
+  adjust_margin (self, &alloc);
+  update_maximum_height (self);
+
+  diff_w = (RATIO_TO_RELATIVE - 1) * alloc.width;
+  diff_h = (RATIO_TO_RELATIVE - 1) * alloc.height;
+
+  gtk_window_move (GTK_WINDOW (self), alloc.x - diff_w / 2, alloc.y - diff_h / 2);
+
+  if (animate)
+    {
+      gtk_widget_set_size_request (GTK_WIDGET (self), alloc.width, alloc.height);
+
+      animate_position (self, 1.0, 1.0);
+      animate_size (self, alloc.width * RATIO_TO_RELATIVE, alloc.height * RATIO_TO_RELATIVE);
+    }
+  else
+    {
+      gtk_widget_set_size_request (GTK_WIDGET (self), alloc.width * RATIO_TO_RELATIVE, alloc.height * 
RATIO_TO_RELATIVE);
+    }
+}
+
+static void
+update_event_list (GcalMonthPopover *self)
+{
+  g_autofree icaltimetype *start = NULL;
+  g_autofree icaltimetype *end = NULL;
+  g_autoptr (GDateTime) start_dt = NULL;
+  g_autoptr (GDateTime) end_dt = NULL;
+  g_autoptr (GList) events = NULL;
+  GList *l;
+
+  gtk_container_foreach (GTK_CONTAINER (self->listbox), (GtkCallback) gtk_widget_destroy, NULL);
+
+  if (!gtk_widget_get_realized (GTK_WIDGET (self)) ||
+      !gtk_widget_get_visible (GTK_WIDGET (self)) ||
+      !self->date)
+    {
+      return;
+    }
+
+  start_dt = g_date_time_new_local (g_date_time_get_year (self->date),
+                                    g_date_time_get_month (self->date),
+                                    g_date_time_get_day_of_month (self->date),
+                                    0, 0, 0);
+  end_dt = g_date_time_add_days (start_dt, 1);
+
+  start = datetime_to_icaltime (start_dt);
+  end = datetime_to_icaltime (end_dt);
+
+  events = gcal_manager_get_events (self->manager, start, end);
+
+  for (l = events; l; l = l->next)
+    {
+      g_autoptr (GDateTime) event_start = NULL;
+      g_autoptr (GDateTime) event_end = NULL;
+      g_autoptr (GTimeZone) tz = NULL;
+      GtkWidget *event_widget;
+      GcalEvent *event;
+
+      event = l->data;
+
+      if (gcal_event_get_all_day (event))
+        tz = g_time_zone_new_utc ();
+      else
+        tz = g_time_zone_new_local ();
+
+      event_start = g_date_time_new (tz,
+                                     g_date_time_get_year (start_dt),
+                                     g_date_time_get_month (start_dt),
+                                     g_date_time_get_day_of_month (start_dt),
+                                     0, 0, 0);
+
+      event_end = g_date_time_add_days (event_start, 1);
+
+      event_widget = gcal_event_widget_new (event);
+      gcal_event_widget_set_date_start (GCAL_EVENT_WIDGET (event_widget), event_start);
+      gcal_event_widget_set_date_end (GCAL_EVENT_WIDGET (event_widget), event_end);
+
+      gtk_container_add (GTK_CONTAINER (self->listbox), event_widget);
+
+      g_signal_connect (event_widget,
+                        "activate",
+                        G_CALLBACK (event_activated_cb),
+                        self);
+    }
+
+  gtk_widget_show_all (self->listbox);
+}
+
+
+/*
+ * Callbacks
+ */
+
+static void
+event_activated_cb (GcalEventWidget  *event_widget,
+                    GcalMonthPopover *self)
+{
+  g_signal_emit (self, signals[EVENT_ACTIVATED], 0, event_widget);
+}
+
+static void
+close_button_clicked_cb (GcalMonthPopover *self)
+{
+  gcal_month_popover_popdown (self);
+}
+
+static void
+new_event_button_clicked_cb (GtkWidget        *button,
+                             GcalMonthPopover *self)
+{
+  GActionMap *map;
+  GAction *action;
+
+  map = G_ACTION_MAP (g_application_get_default ());
+  action = g_action_map_lookup_action (map, "new");
+
+  g_action_activate (action, NULL);
+
+  //gcal_month_popover_popdown (self);
+}
+
+static void
+revealer_notify_child_revealed_cb (GcalMonthPopover *self,
+                                   GParamSpec       *pspec,
+                                   GtkRevealer      *revealer)
+{
+  if (!gtk_revealer_get_reveal_child (self->revealer))
+    gtk_widget_hide (GTK_WIDGET (self));
+}
+
+static gboolean
+transient_for_configure_event_cb (GcalMonthPopover *self,
+                                  GdkEvent         *event,
+                                  GtkWindow        *toplevel)
+{
+  gtk_widget_hide (GTK_WIDGET (self));
+  return FALSE;
+}
+
+static gboolean
+transient_for_delete_event_cb (GcalMonthPopover *self,
+                               GdkEvent         *event,
+                               GtkWindow        *toplevel)
+{
+  gtk_widget_hide (GTK_WIDGET (self));
+  return FALSE;
+}
+
+static void
+transient_for_size_allocate_cb (GcalMonthPopover *self,
+                                GtkAllocation    *allocation,
+                                GtkWindow        *toplevel)
+{
+  reposition_popover (self, FALSE);
+}
+
+
+/*
+ * GtkWidget overrides
+ */
+
+static void
+gcal_month_popover_destroy (GtkWidget *widget)
+{
+  GcalMonthPopover *self = (GcalMonthPopover *)widget;
+
+  if (self->transient_for)
+    {
+      g_signal_handler_disconnect (self->transient_for, self->size_allocate_handler);
+      g_signal_handler_disconnect (self->transient_for, self->configure_event_handler);
+      g_signal_handler_disconnect (self->transient_for, self->delete_event_handler);
+
+      self->size_allocate_handler = 0;
+      self->configure_event_handler = 0;
+      self->delete_event_handler = 0;
+
+      self->transient_for = NULL;
+    }
+
+  if (self->opacity_animation)
+    {
+      dzl_animation_stop (self->opacity_animation);
+      dzl_clear_weak_pointer (&self->opacity_animation);
+    }
+
+  if (self->position_animation)
+    {
+      dzl_animation_stop (self->position_animation);
+      dzl_clear_weak_pointer (&self->position_animation);
+    }
+
+  if (self->size_animation)
+    {
+      dzl_animation_stop (self->size_animation);
+      dzl_clear_weak_pointer (&self->size_animation);
+    }
+
+  gcal_month_popover_set_relative_to (self, NULL);
+
+  GTK_WIDGET_CLASS (gcal_month_popover_parent_class)->destroy (widget);
+}
+
+static gboolean
+gcal_month_popover_focus_out_event (GtkWidget     *widget,
+                                    GdkEventFocus *event_focus)
+{
+  gcal_month_popover_popdown (GCAL_MONTH_POPOVER (widget));
+
+  return GTK_WIDGET_CLASS (gcal_month_popover_parent_class)->focus_out_event (widget, event_focus);
+}
+
+static void
+gcal_month_popover_hide (GtkWidget *widget)
+{
+  GcalMonthPopover *self = (GcalMonthPopover *)widget;
+
+  if (self->transient_for)
+    gtk_window_group_remove_window (gtk_window_get_group (self->transient_for), GTK_WINDOW (self));
+
+  g_signal_handler_disconnect (self->transient_for, self->delete_event_handler);
+  g_signal_handler_disconnect (self->transient_for, self->size_allocate_handler);
+  g_signal_handler_disconnect (self->transient_for, self->configure_event_handler);
+
+  self->delete_event_handler = 0;
+  self->size_allocate_handler = 0;
+  self->configure_event_handler = 0;
+
+  self->transient_for = NULL;
+
+  gcal_month_popover_popdown (self);
+
+  GTK_WIDGET_CLASS (gcal_month_popover_parent_class)->hide (widget);
+}
+
+static void
+gcal_month_popover_show (GtkWidget *widget)
+{
+  GcalMonthPopover *self = (GcalMonthPopover *)widget;
+
+  if (self->relative_to)
+    {
+      GtkWidget *toplevel;
+
+      toplevel = gtk_widget_get_ancestor (GTK_WIDGET (self->relative_to), GTK_TYPE_WINDOW);
+
+      if (GTK_IS_WINDOW (toplevel))
+        {
+          self->transient_for = GTK_WINDOW (toplevel);
+
+          gtk_window_group_add_window (gtk_window_get_group (self->transient_for), GTK_WINDOW (self));
+
+          self->delete_event_handler =
+            g_signal_connect_object (toplevel,
+                                     "delete-event",
+                                     G_CALLBACK (transient_for_delete_event_cb),
+                                     self,
+                                     G_CONNECT_SWAPPED);
+
+          self->size_allocate_handler =
+            g_signal_connect_object (toplevel,
+                                     "size-allocate",
+                                     G_CALLBACK (transient_for_size_allocate_cb),
+                                     self,
+                                     G_CONNECT_SWAPPED | G_CONNECT_AFTER);
+
+          self->configure_event_handler =
+            g_signal_connect_object (toplevel,
+                                     "configure-event",
+                                     G_CALLBACK (transient_for_configure_event_cb),
+                                     self,
+                                     G_CONNECT_SWAPPED);
+
+          gtk_window_set_transient_for (GTK_WINDOW (self), self->transient_for);
+
+          reposition_popover (self, FALSE);
+        }
+    }
+
+  GTK_WIDGET_CLASS (gcal_month_popover_parent_class)->show (widget);
+}
+
+static void
+gcal_month_popover_realize (GtkWidget *widget)
+{
+  GcalMonthPopover *self = (GcalMonthPopover *)widget;
+  GdkScreen *screen;
+  GdkVisual *visual;
+
+  screen = gtk_widget_get_screen (widget);
+  visual = gdk_screen_get_rgba_visual (screen);
+
+  if (visual)
+    gtk_widget_set_visual (widget, visual);
+
+  GTK_WIDGET_CLASS (gcal_month_popover_parent_class)->realize (widget);
+
+  reposition_popover (self, TRUE);
+}
+
+
+/*
+ * GObject overrides
+ */
+
+static void
+gcal_month_popover_get_property (GObject    *object,
+                                 guint       prop_id,
+                                 GValue     *value,
+                                 GParamSpec *pspec)
+{
+  GcalMonthPopover *self = GCAL_MONTH_POPOVER (object);
+
+  switch (prop_id)
+    {
+    case PROP_MANAGER:
+      g_value_set_object (value, self->manager);
+      break;
+
+    case PROP_RELATIVE_TO:
+      g_value_set_object (value, self->relative_to);
+      break;
+
+    case PROP_X:
+      g_value_set_double (value, self->x_ratio);
+      break;
+
+    case PROP_Y:
+      g_value_set_double (value, self->y_ratio);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gcal_month_popover_set_property (GObject      *object,
+                                 guint         prop_id,
+                                 const GValue *value,
+                                 GParamSpec   *pspec)
+{
+  GcalMonthPopover *self = GCAL_MONTH_POPOVER (object);
+
+  switch (prop_id)
+    {
+    case PROP_MANAGER:
+      self->manager = g_value_dup_object (value);
+      break;
+
+    case PROP_RELATIVE_TO:
+      gcal_month_popover_set_relative_to (self, g_value_get_object (value));
+      break;
+
+    case PROP_X:
+      self->x_ratio = g_value_get_double (value);
+      update_position (self);
+      break;
+
+
+    case PROP_Y:
+      self->y_ratio = g_value_get_double (value);
+      update_position (self);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gcal_month_popover_class_init (GcalMonthPopoverClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->get_property = gcal_month_popover_get_property;
+  object_class->set_property = gcal_month_popover_set_property;
+
+  widget_class->destroy = gcal_month_popover_destroy;
+  widget_class->focus_out_event = gcal_month_popover_focus_out_event;
+  widget_class->hide = gcal_month_popover_hide;
+  widget_class->show = gcal_month_popover_show;
+  widget_class->realize = gcal_month_popover_realize;
+
+  properties [PROP_MANAGER] = g_param_spec_object ("manager",
+                                                   "Manager",
+                                                   "Manager",
+                                                   GCAL_TYPE_MANAGER,
+                                                   (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | 
G_PARAM_STATIC_STRINGS));
+
+  properties [PROP_RELATIVE_TO] = g_param_spec_object ("relative-to",
+                                                       "Relative To",
+                                                       "The widget to be relative to",
+                                                       GTK_TYPE_WIDGET,
+                                                       (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | 
G_PARAM_STATIC_STRINGS));
+
+  properties [PROP_X] = g_param_spec_double ("x",
+                                             "X Percent position",
+                                             "X Percent position",
+                                             0.0,
+                                             1.0,
+                                             0.0,
+                                             (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | 
G_PARAM_STATIC_STRINGS));
+
+  properties [PROP_Y] = g_param_spec_double ("y",
+                                             "Y Percent position",
+                                             "Y Percent position",
+                                             0.0,
+                                             1.0,
+                                             0.0,
+                                             (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | 
G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+
+  signals[EVENT_ACTIVATED] = g_signal_new ("event-activated",
+                                           GCAL_TYPE_MONTH_POPOVER,
+                                           G_SIGNAL_RUN_FIRST,
+                                           0,  NULL, NULL, NULL,
+                                           G_TYPE_NONE,
+                                           1,
+                                           GCAL_TYPE_EVENT_WIDGET);
+
+  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/calendar/month-popover.ui");
+
+  gtk_widget_class_bind_template_callback (widget_class, close_button_clicked_cb);
+  gtk_widget_class_bind_template_callback (widget_class, new_event_button_clicked_cb);
+
+  gtk_widget_class_bind_template_child (widget_class, GcalMonthPopover, day_label);
+  gtk_widget_class_bind_template_child (widget_class, GcalMonthPopover, listbox);
+  gtk_widget_class_bind_template_child (widget_class, GcalMonthPopover, revealer);
+  gtk_widget_class_bind_template_child (widget_class, GcalMonthPopover, scrolled_window);
+
+  gtk_widget_class_set_css_name (widget_class, "monthpopover");
+}
+
+static void
+gcal_month_popover_init (GcalMonthPopover *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+
+  gtk_window_set_type_hint (GTK_WINDOW (self), GDK_WINDOW_TYPE_HINT_COMBO);
+  gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
+  gtk_window_set_resizable (GTK_WINDOW (self), FALSE);
+  gtk_window_set_skip_pager_hint (GTK_WINDOW (self), TRUE);
+  gtk_window_set_skip_taskbar_hint (GTK_WINDOW (self), TRUE);
+
+  g_signal_connect_object (self->revealer,
+                           "notify::child-revealed",
+                           G_CALLBACK (revealer_notify_child_revealed_cb),
+                           self,
+                           G_CONNECT_SWAPPED);
+}
+
+GtkWidget*
+gcal_month_popover_new (void)
+{
+  return g_object_new (GCAL_TYPE_MONTH_POPOVER,
+                       "type", GTK_WINDOW_POPUP,
+                       NULL);
+}
+
+void
+gcal_month_popover_set_relative_to (GcalMonthPopover *self,
+                                    GtkWidget        *relative_to)
+{
+  g_return_if_fail (GCAL_MONTH_POPOVER (self));
+  g_return_if_fail (!relative_to || GTK_IS_WIDGET (relative_to));
+
+  if (self->relative_to == relative_to)
+    return;
+
+  if (self->relative_to)
+    {
+      g_signal_handlers_disconnect_by_func (self->relative_to, gtk_widget_destroyed, &self->relative_to);
+      self->relative_to = NULL;
+    }
+
+  if (relative_to)
+    {
+      self->relative_to = relative_to;
+      g_signal_connect (self->relative_to,
+                        "destroy",
+                        G_CALLBACK (gtk_widget_destroyed),
+                        &self->relative_to);
+    }
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_RELATIVE_TO]);
+}
+
+void
+gcal_month_popover_popup (GcalMonthPopover *self)
+{
+  gint duration = 250;
+
+  g_return_if_fail (GCAL_IS_MONTH_POPOVER (self));
+
+  if (self->relative_to)
+    {
+      GtkAllocation alloc;
+      GdkDisplay *display;
+      GdkMonitor *monitor;
+      GdkWindow *window;
+      gint min_height;
+      gint nat_height;
+
+      display = gtk_widget_get_display (GTK_WIDGET (self->relative_to));
+      window = gtk_widget_get_window (GTK_WIDGET (self->relative_to));
+      monitor = gdk_display_get_monitor_at_window (display, window);
+
+      gtk_widget_get_preferred_height (GTK_WIDGET (self), &min_height, &nat_height);
+      gtk_widget_get_allocation (GTK_WIDGET (self), &alloc);
+
+      duration = dzl_animation_calculate_duration (monitor, alloc.height, nat_height);
+    }
+
+  gtk_widget_show (GTK_WIDGET (self));
+
+  gtk_revealer_set_transition_duration (self->revealer, duration);
+  gtk_revealer_set_reveal_child (self->revealer, TRUE);
+
+  update_event_list (self);
+
+  gtk_widget_grab_focus (GTK_WIDGET (self));
+
+  /* Animations */
+  animate_opacity (self, 1.0);
+  reposition_popover (self, TRUE);
+}
+
+void
+gcal_month_popover_popdown (GcalMonthPopover *self)
+{
+  GtkAllocation alloc;
+  GdkDisplay *display;
+  GdkMonitor *monitor;
+  GdkWindow *window;
+  guint duration;
+
+  g_return_if_fail (GCAL_IS_MONTH_POPOVER (self));
+
+  if (!gtk_widget_get_realized (GTK_WIDGET (self)))
+    return;
+
+  display = gtk_widget_get_display (GTK_WIDGET (self->relative_to));
+  window = gtk_widget_get_window (GTK_WIDGET (self->relative_to));
+  monitor = gdk_display_get_monitor_at_window (display, window);
+
+  gtk_widget_get_allocation (GTK_WIDGET (self), &alloc);
+
+  duration = dzl_animation_calculate_duration (monitor, alloc.height, 0);
+
+  gtk_revealer_set_transition_duration (self->revealer, duration);
+  gtk_revealer_set_reveal_child (self->revealer, FALSE);
+
+  /* Animations */
+  gtk_widget_get_allocation (GTK_WIDGET (self->relative_to), &alloc);
+  gtk_widget_translate_coordinates (self->relative_to,
+                                    gtk_widget_get_toplevel (self->relative_to), 0, 0, &alloc.x, &alloc.y);
+  adjust_margin (self, &alloc);
+
+  animate_opacity (self, 0.0);
+  animate_position (self, 0.0, 0.0);
+  animate_size (self, alloc.width, alloc.height);
+}
+
+GDateTime*
+gcal_month_popover_get_date (GcalMonthPopover *self)
+{
+  g_return_val_if_fail (GCAL_IS_MONTH_POPOVER (self), NULL);
+
+  return self->date;
+}
+
+void
+gcal_month_popover_set_date (GcalMonthPopover *self,
+                             GDateTime        *date)
+{
+  g_return_if_fail (GCAL_IS_MONTH_POPOVER (self));
+
+  if (date && self->date && datetime_compare_date (self->date, date) == 0)
+    return;
+
+  gcal_clear_datetime (&self->date);
+
+  if (date)
+    {
+      g_autofree gchar *label;
+
+      self->date = g_date_time_ref (date);
+
+      label = g_strdup_printf ("%d", g_date_time_get_day_of_month (date));
+      gtk_label_set_label (self->day_label, label);
+    }
+
+  update_event_list (self);
+}
diff --git a/src/views/gcal-month-popover.h b/src/views/gcal-month-popover.h
new file mode 100644
index 0000000..83c7b45
--- /dev/null
+++ b/src/views/gcal-month-popover.h
@@ -0,0 +1,50 @@
+/* gcal-month-popover.h
+ *
+ * Copyright © 2017 Georges Basile Stavracas Neto <georges stavracas gmail 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 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/>.
+ */
+
+#ifndef GCAL_MONTH_POPOVER_H
+#define GCAL_MONTH_POPOVER_H
+
+#include "gcal-manager.h"
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GCAL_TYPE_MONTH_POPOVER (gcal_month_popover_get_type())
+
+G_DECLARE_FINAL_TYPE (GcalMonthPopover, gcal_month_popover, GCAL, MONTH_POPOVER, GtkWindow)
+
+GtkWidget*           gcal_month_popover_new                      (void);
+
+
+void                 gcal_month_popover_set_relative_to          (GcalMonthPopover   *self,
+                                                                  GtkWidget          *relative_to);
+
+void                 gcal_month_popover_popup                    (GcalMonthPopover   *self);
+
+void                 gcal_month_popover_popdown                  (GcalMonthPopover   *self);
+
+GDateTime*           gcal_month_popover_get_date                 (GcalMonthPopover   *self);
+
+void                 gcal_month_popover_set_date                 (GcalMonthPopover   *self,
+                                                                  GDateTime          *date);
+
+G_END_DECLS
+
+#endif /* GCAL_MONTH_POPOVER_H */
+
diff --git a/src/views/gcal-month-view.c b/src/views/gcal-month-view.c
index daf246d..7387e4e 100644
--- a/src/views/gcal-month-view.c
+++ b/src/views/gcal-month-view.c
@@ -27,6 +27,7 @@
 
 #include "gcal-debug.h"
 #include "gcal-month-cell.h"
+#include "gcal-month-popover.h"
 #include "gcal-month-view.h"
 #include "gcal-utils.h"
 #include "gcal-view.h"
@@ -41,9 +42,7 @@ struct _GcalMonthView
 {
   GtkContainer        parent;
 
-  GtkWidget          *events_box;
-  GtkWidget          *overflow_popover;
-  GtkWidget          *popover_title;
+  GcalMonthPopover   *overflow_popover;
 
   GdkWindow          *event_window;
 
@@ -185,11 +184,12 @@ cancel_selection (GcalMonthView *self)
 }
 
 static void
-event_activated (GcalEventWidget *widget,
-                 GcalMonthView   *self)
+event_activated (GcalMonthView   *self,
+                 GcalEventWidget *widget,
+                 gpointer         unused)
 {
   cancel_selection (self);
-  gtk_widget_hide (self->overflow_popover);
+  gcal_month_popover_popdown (self->overflow_popover);
 
   g_signal_emit (self, signals[EVENT_ACTIVATED], 0, widget);
 }
@@ -201,7 +201,7 @@ setup_child_widget (GcalMonthView *self,
   if (!gtk_widget_get_parent (widget))
     gtk_widget_set_parent (widget, GTK_WIDGET (self));
 
-  g_signal_connect (widget, "activate", G_CALLBACK (event_activated), self);
+  g_signal_connect_swapped (widget, "activate", G_CALLBACK (event_activated), self);
   g_signal_connect_swapped (widget, "hide", G_CALLBACK (gtk_widget_queue_resize), self);
   g_signal_connect_swapped (widget, "show", G_CALLBACK (gtk_widget_queue_resize), self);
 }
@@ -385,78 +385,15 @@ show_overflow_popover_cb (GcalMonthCell *cell,
                           GtkWidget     *button,
                           GcalMonthView *self)
 {
-  g_autofree gchar *label_title = NULL;
-  GtkWidget *child_widget;
-  GDateTime *dt;
-  GList *l;
-  gint day, cell_nr;
-
-  dt = gcal_month_cell_get_date (cell);
-  day = g_date_time_get_day_of_month (dt);
-  cell_nr = day + self->days_delay - 1;
-
-  if (!g_hash_table_contains (self->overflow_cells, GINT_TO_POINTER (cell_nr)))
-    {
-      g_critical ("No overflow events for day %d. Something is wrong.", cell_nr);
-      return;
-    }
-
-  /* Popover title */
-  label_title = g_date_time_format (dt, _("%B %d"));
-  gtk_label_set_text (GTK_LABEL (self->popover_title), label_title);
-
-  /* Clean all the widgets */
-  gtk_container_foreach (GTK_CONTAINER (self->events_box), (GtkCallback) gtk_widget_destroy, NULL);
-
-  l = g_hash_table_lookup (self->overflow_cells, GINT_TO_POINTER (cell_nr));
-
-  /* Setup the start & end dates of the events as the begin & end of day */
-  for (; l != NULL; l = g_list_next (l))
-    {
-      g_autoptr (GDateTime) current_date = NULL;
-      g_autoptr (GDateTime) dt_start = NULL;
-      g_autoptr (GDateTime) dt_end = NULL;
-      g_autoptr (GTimeZone) tz = NULL;
-      GtkWidget *cloned_event;
-      GcalEvent *event;
-
-      event = gcal_event_widget_get_event (l->data);
-
-      if (gcal_event_get_all_day (event))
-        tz = g_time_zone_new_utc ();
-      else
-        tz = g_time_zone_new_local ();
-
-      current_date = icaltime_to_datetime (self->date);
-      dt_start = g_date_time_new (tz,
-                                  g_date_time_get_year (current_date),
-                                  g_date_time_get_month (current_date),
-                                  day, 0, 0, 0);
-
-      dt_end = g_date_time_add_days (dt_start, 1);
-
-      cloned_event = gcal_event_widget_clone (l->data);
-      gcal_event_widget_set_date_start (GCAL_EVENT_WIDGET (cloned_event), dt_start);
-      gcal_event_widget_set_date_end (GCAL_EVENT_WIDGET (cloned_event), dt_end);
-
-      gtk_container_add (GTK_CONTAINER (self->events_box), cloned_event);
-      setup_child_widget (self, cloned_event);
-    }
-
-  gtk_popover_set_relative_to (GTK_POPOVER (self->overflow_popover), button);
-
-  /* sizing hack */
-  child_widget = gtk_bin_get_child (GTK_BIN (self->overflow_popover));
-  gtk_widget_set_size_request (child_widget, 200, -1);
-  gtk_widget_show_all (child_widget);
+  GcalMonthPopover *popover;
 
-  g_object_set_data (G_OBJECT (self->overflow_popover),
-                     "selected-day",
-                     GINT_TO_POINTER (day));
-
-  gtk_popover_popup (GTK_POPOVER (self->overflow_popover));
+  popover = GCAL_MONTH_POPOVER (self->overflow_popover);
 
   cancel_selection (self);
+
+  gcal_month_popover_set_relative_to (popover, GTK_WIDGET (cell));
+  gcal_month_popover_set_date (popover, gcal_month_cell_get_date (cell));
+  gcal_month_popover_popup (popover);
 }
 
 static void
@@ -761,16 +698,6 @@ gcal_month_view_key_press (GtkWidget   *widget,
 }
 
 static gboolean
-cancel_dnd_from_overflow_popover (GtkPopover *popover)
-{
-  GCAL_ENTRY;
-
-  gtk_popover_popdown (popover);
-
-  GCAL_RETURN (FALSE);
-}
-
-static gboolean
 gcal_month_view_scroll_event (GtkWidget      *widget,
                               GdkEventScroll *scroll_event)
 {
@@ -799,12 +726,12 @@ add_new_event_button_cb (GtkWidget *button,
                          gpointer   user_data)
 {
   GcalMonthView *self;
-  gint day;
   GDateTime *start_date;
+  gint day;
 
   self = GCAL_MONTH_VIEW (user_data);
 
-  gtk_widget_hide (self->overflow_popover);
+  gcal_month_popover_popdown (self->overflow_popover);
 
   day = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (self->overflow_popover), "selected-day"));
   start_date = g_date_time_new_local (self->date->year, self->date->month, day, 0, 0, 0);
@@ -2045,7 +1972,7 @@ gcal_month_view_motion_notify_event (GtkWidget      *widget,
     }
   else
     {
-      if (gtk_widget_is_visible (self->overflow_popover))
+      if (gtk_widget_is_visible (GTK_WIDGET (self->overflow_popover)))
         GCAL_RETURN (GDK_EVENT_PROPAGATE);
     }
 
@@ -2159,7 +2086,6 @@ gcal_month_view_class_init (GcalMonthViewClass *klass)
 
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/calendar/month-view.ui");
 
-  gtk_widget_class_bind_template_child (widget_class, GcalMonthView, events_box);
   gtk_widget_class_bind_template_child (widget_class, GcalMonthView, label_0);
   gtk_widget_class_bind_template_child (widget_class, GcalMonthView, label_1);
   gtk_widget_class_bind_template_child (widget_class, GcalMonthView, label_2);
@@ -2168,14 +2094,13 @@ gcal_month_view_class_init (GcalMonthViewClass *klass)
   gtk_widget_class_bind_template_child (widget_class, GcalMonthView, label_5);
   gtk_widget_class_bind_template_child (widget_class, GcalMonthView, label_6);
   gtk_widget_class_bind_template_child (widget_class, GcalMonthView, month_label);
-  gtk_widget_class_bind_template_child (widget_class, GcalMonthView, overflow_popover);
-  gtk_widget_class_bind_template_child (widget_class, GcalMonthView, popover_title);
   gtk_widget_class_bind_template_child (widget_class, GcalMonthView, year_label);
 
   gtk_widget_class_bind_template_callback (widget_class, add_new_event_button_cb);
-  gtk_widget_class_bind_template_callback (widget_class, cancel_dnd_from_overflow_popover);
 
   gtk_widget_class_set_css_name (widget_class, "calendar-view");
+
+  g_type_ensure (GCAL_TYPE_MONTH_POPOVER);
 }
 
 static void
@@ -2193,17 +2118,6 @@ gcal_month_view_init (GcalMonthView *self)
 
   self->k = gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL;
 
-  /*
-   * Also set the overflow popover as a drop destination, so we can hide
-   * it when the user starts dragging an event that is inside the overflow
-   * list.
-   */
-  gtk_drag_dest_set (GTK_WIDGET (self->overflow_popover),
-                     0,
-                     NULL,
-                     0,
-                     GDK_ACTION_MOVE);
-
   /* Weekday header labels */
   self->weekday_label[0] = self->label_0;
   self->weekday_label[1] = self->label_1;
@@ -2214,6 +2128,20 @@ gcal_month_view_init (GcalMonthView *self)
   self->weekday_label[6] = self->label_6;
 
   update_weekday_labels (self);
+
+  /* Overflow popover */
+  self->overflow_popover = (GcalMonthPopover*) gcal_month_popover_new ();
+
+  g_object_bind_property (self,
+                          "manager",
+                          self->overflow_popover,
+                          "manager",
+                          G_BINDING_DEFAULT);
+
+  g_signal_connect_swapped (self->overflow_popover,
+                            "event-activated",
+                            G_CALLBACK (event_activated),
+                            self);
 }
 
 /* Public API */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]