<commit_before>/* This file is part of herzi's playground
 *
 * Copyright (C) 2010  <NAME>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

#include "workspace-button.h"
#include "window-menu-item.h"
#include <glib/gi18n.h>

struct _WorkspaceButtonPrivate
{
  GtkWidget* label;
  WnckWorkspace* workspace;
};

enum
{
  PROP_0,
  PROP_WORKSPACE
};

#define PRIV(i) (((WorkspaceButton*)(i))->_private)

static GtkWidget* menu = NULL;

G_DEFINE_TYPE (WorkspaceButton, workspace_button, GTK_TYPE_TOGGLE_BUTTON);

#if 0
static void
select_cb (GtkItem * item,
           gpointer  user_data)
{
  gchar* text = g_strdup_printf (_("%s (rename)"),
                                 wnck_workspace_get_name (user_data));
  gtk_menu_item_set_label (GTK_MENU_ITEM (item), text);
  g_free (text);
}

static void
unselect_cb (GtkItem * item,
             gpointer  user_data)
{
  gtk_menu_item_set_label (GTK_MENU_ITEM (item),
                           wnck_workspace_get_name (user_data));
}
#endif

static void
untoggle (GtkWidget* widget,
          gpointer   user_data)
{
  gtk_toggle_button_set_active (user_data, FALSE);

  gtk_widget_destroy (widget);
  g_object_unref (widget);
  menu = NULL;
}

static void
button_toggled_cb (GtkToggleButton* button)
{
  if (gtk_toggle_button_get_active (button))
    {
      GtkWidget* item = NULL;
      GList    * window;

      g_return_if_fail (!menu);

      menu = g_object_ref_sink (gtk_menu_new ());
      item = gtk_menu_item_new_with_label (wnck_workspace_get_name (PRIV (button)->workspace));
      gtk_widget_set_sensitive (item, FALSE);
#if 0
      g_signal_connect (item, "select",
                        G_CALLBACK (select_cb), PRIV (button)->workspace);
      g_signal_connect (item, "deselect",
                        G_CALLBACK (unselect_cb), PRIV (button)->workspace);
#endif
      gtk_widget_show (item);
      gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);

      item = gtk_separator_menu_item_new ();
      gtk_widget_show (item);
      gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);

      for (window = wnck_screen_get_windows (wnck_workspace_get_screen (PRIV (button)->workspace)); window; window = window->next)
        {
          if (!wnck_window_is_on_workspace (window->data, PRIV (button)->workspace) ||
              (wnck_window_get_state (window->data) & WNCK_WINDOW_STATE_SKIP_PAGER))
            {
              continue;
            }

          item = window_menu_item_new (window->data);
          gtk_widget_show (item);
          gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
        }

      gtk_menu_attach_to_widget (GTK_MENU (menu),
                                 GTK_WIDGET (button),
                                 NULL);

      gtk_menu_popup (GTK_MENU (menu),
                      NULL, NULL,
                      NULL,
                      NULL,
                      0, gtk_get_current_event_time ());

      g_object_add_weak_pointer (G_OBJECT (menu), (gpointer*)&menu);

      g_signal_connect (menu, "selection-done",
                        G_CALLBACK (untoggle), button);
    }
}

static void
workspace_button_init (WorkspaceButton* self)
{
  PRIV (self) = G_TYPE_INSTANCE_GET_PRIVATE (self, WORKSPACE_TYPE_BUTTON, WorkspaceButtonPrivate);
  PRIV (self)->label = gtk_label_new (NULL);<commit_msg>started a menu_position function for the popups<commit_after>/* This file is part of herzi's playground
 *
 * Copyright (C) 2010  <NAME>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

#include "workspace-button.h"
#include "window-menu-item.h"
#include <glib/gi18n.h>

struct _WorkspaceButtonPrivate
{
  GtkWidget* label;
  WnckWorkspace* workspace;
};

enum
{
  PROP_0,
  PROP_WORKSPACE
};

#define PRIV(i) (((WorkspaceButton*)(i))->_private)

static GtkWidget* menu = NULL;

G_DEFINE_TYPE (WorkspaceButton, workspace_button, GTK_TYPE_TOGGLE_BUTTON);

#if 0
static void
select_cb (GtkItem * item,
           gpointer  user_data)
{
  gchar* text = g_strdup_printf (_("%s (rename)"),
                                 wnck_workspace_get_name (user_data));
  gtk_menu_item_set_label (GTK_MENU_ITEM (item), text);
  g_free (text);
}

static void
unselect_cb (GtkItem * item,
             gpointer  user_data)
{
  gtk_menu_item_set_label (GTK_MENU_ITEM (item),
                           wnck_workspace_get_name (user_data));
}
#endif

static void
untoggle (GtkWidget* widget,
          gpointer   user_data)
{
  gtk_toggle_button_set_active (user_data, FALSE);

  gtk_widget_destroy (widget);
  g_object_unref (widget);
  menu = NULL;
}

static void
menu_position_func (GtkMenu * menu,
                    gint    * x,
                    gint    * y,
                    gboolean* push_in,
                    gpointer  user_data)
{
  GtkRequisition  requisition;
  GtkAllocation   allocation;
  GdkRectangle    monitor_geometry;
  GdkScreen     * screen;
  int             monitor;

  screen = gtk_widget_get_screen (GTK_WIDGET (menu));

  gtk_widget_get_allocation (user_data, &allocation);
  gtk_widget_size_request (GTK_WIDGET (menu), &requisition);

  gdk_window_get_root_coords (gtk_widget_get_parent_window (user_data),
                              allocation.x, allocation.y,
                              &allocation.x, &allocation.y);

  monitor = gdk_screen_get_monitor_at_window (screen, GTK_WIDGET (user_data)->window);
  gdk_screen_get_monitor_geometry (screen, monitor, &monitor_geometry);

  if (allocation.y >= monitor_geometry.y &&
      allocation.y + allocation.height + requisition.height <= monitor_geometry.y + monitor_geometry.height)
    {
      *y = allocation.y + allocation.height;
    }
  else
    {
      g_warning ("implement menu-on-top");
      *y = allocation.y;
    }

  *x = allocation.x;

  //gtk_menu_set_monitor (menu, monitor);
}

static void
button_toggled_cb (GtkToggleButton* button)
{
  if (gtk_toggle_button_get_active (button))
    {
      GtkWidget* item = NULL;
      GList    * window;

      g_return_if_fail (!menu);

      menu = g_object_ref_sink (gtk_menu_new ());
      item = gtk_menu_item_new_with_label (wnck_workspace_get_name (PRIV (button)->workspace));
      //gtk_widget_set_sensitive (item, FALSE);
#if 0
      g_signal_connect (item, "select",
                        G_CALLBACK (select_cb), PRIV (button)->workspace);
      g_signal_connect (item, "deselect",
                        G_CALLBACK (unselect_cb), PRIV (button)->workspace);
#endif
      gtk_widget_show (item);
      gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);

      item = gtk_separator_menu_item_new ();
      gtk_widget_show (item);
      gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);

      for (window = wnck_screen_get_windows (wnck_workspace_get_screen (PRIV (button)->workspace)); window; window = window->next)
        {
          if (!wnck_window_is_on_workspace (window->data, PRIV (button)->workspace) ||
              (wnck_window_get_state (window->data) & WNCK_WINDOW_STATE_SKIP_PAGER))
            {
              continue;
            }

          item = window_menu_item_new (window->data);
          gtk_widget_show (item);
          gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
        }

      gtk_menu_attach_to_widget (GTK_MENU (menu),
                                 GTK_WIDGET (button),
                                 NULL);

      gtk_menu_set_screen (GTK_MENU (menu),
                           gtk_widget_get_screen (GTK_WIDGET (button)));
      gtk_menu_popup (GTK_MENU (menu),
                      NULL, NULL,
                      menu_position_func, button,
                      0, gtk_get_current_event_time ());

      g_object_add_weak_pointer (G_OBJECT (menu), (gpointer*)&menu);

      g_signal_connect (menu, "selection-done",
                        G_CALLBACK (untoggle), button);
    }
}

static void
workspace_button_init (WorkspaceButton* self)
{
  PRIV (self) = G_TYPE_INSTANCE_GET_PRIVATE (self, WORKSPACE_TYPE_BUTTON, WorkspaceButtonPrivate);
  PRIV (self)->label = gtk_label_new (NULL);
{'fraction_non_alphanumeric': 0.09335746220992122, 'fraction_numerical': 0.005535448158398978, 'mean_word_length': 2.8237688237688237, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '68429', 'n_tokens_mistral': 3117, 'n_tokens_neox': 2994, 'n_words': 741}