static void
go_combo_box_popup_hide_unconditional (GOComboBox *combo_box)
{
	gboolean popup_info_destroyed = FALSE;
	GObject *pdc;

	g_return_if_fail (combo_box != NULL);
	g_return_if_fail (GO_IS_COMBO_BOX (combo_box));

	gtk_widget_hide (combo_box->priv->toplevel);
	gtk_widget_hide (combo_box->priv->popup);
	if (combo_box->priv->torn_off)
		go_combo_set_tearoff_state (combo_box, FALSE);

	do_focus_change (combo_box->priv->toplevel, FALSE);
	gtk_grab_remove (combo_box->priv->toplevel);
	gdk_device_ungrab (gtk_get_current_event_device (),
	                   GDK_CURRENT_TIME);

	pdc = g_object_ref (combo_box->priv->popdown_container);
	g_signal_emit (combo_box,
		       go_combo_box_signals [POP_DOWN_DONE], 0,
		       pdc, &popup_info_destroyed);

	if (popup_info_destroyed){
		gtk_container_remove (
			GTK_CONTAINER (combo_box->priv->frame),
			combo_box->priv->popdown_container);
		combo_box->priv->popdown_container = NULL;
	}
	g_object_unref (pdc);
	set_arrow_state (combo_box, FALSE);
}
示例#2
0
文件: testsocket.c 项目: BYC/gtk
static void
grab_window_toggled (GtkToggleButton *button,
		     GtkWidget       *widget)
{
  GdkDevice *device = gtk_get_current_event_device ();

  if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
    device = gdk_device_get_associated_device (device);

  if (gtk_toggle_button_get_active (button))
    {
      int status;

      status = gdk_device_grab (device,
                                gtk_widget_get_window (widget),
                                GDK_OWNERSHIP_NONE,
                                FALSE,
                                GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
                                NULL,
                                GDK_CURRENT_TIME);

      if (status != GDK_GRAB_SUCCESS)
	g_warning ("Could not grab keyboard!  (%s)", grab_string (status));

    } 
  else 
    {
      gdk_device_ungrab (device, GDK_CURRENT_TIME);
    }
}
示例#3
0
static void
nemo_query_editor_grab_focus (GtkWidget *widget)
{
	NemoQueryEditor *editor = NEMO_QUERY_EDITOR (widget);

	if (gtk_widget_get_visible (widget)) {
		entry_focus_hack (editor->details->entry, gtk_get_current_event_device ());
	}
}
示例#4
0
/* Asks the user to click on a window, then waits for them click
 * the mouse. When the mouse is released, returns the toplevel
 * window under the pointer, or NULL, if there is none.
 */
static GtkWidget *
query_for_toplevel (GdkScreen  *screen,
                    const char *prompt)
{
  GdkDisplay *display = gdk_screen_get_display (screen);
  GtkWidget *popup, *label, *frame;
  GdkCursor *cursor;
  GtkWidget *toplevel = NULL;

  popup = gtk_window_new (GTK_WINDOW_POPUP);
  gtk_window_set_screen (GTK_WINDOW (popup), screen);
  gtk_window_set_modal (GTK_WINDOW (popup), TRUE);
  gtk_window_set_position (GTK_WINDOW (popup), GTK_WIN_POS_CENTER);

  frame = gtk_frame_new (NULL);
  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
  gtk_container_add (GTK_CONTAINER (popup), frame);

  label = gtk_label_new (prompt);
  g_object_set (label, "margin", 10, NULL);
  gtk_container_add (GTK_CONTAINER (frame), label);

  gtk_widget_show_all (popup);
  cursor = gdk_cursor_new_from_name (display, "crosshair");

  if (gdk_device_grab (gtk_get_current_event_device (),
                       gtk_widget_get_window (popup),
                       GDK_OWNERSHIP_NONE,
                       FALSE,
                       GDK_BUTTON_RELEASE_MASK,
                       cursor,
                       GDK_CURRENT_TIME) == GDK_GRAB_SUCCESS)
    {
      gboolean clicked = FALSE;

      g_signal_connect (popup, "button-release-event",
                        G_CALLBACK (button_release_event_cb), &clicked);

      /* Process events until clicked is set by button_release_event_cb.
       * We pass in may_block=TRUE since we want to wait if there
       * are no events currently.
       */
      while (!clicked)
        g_main_context_iteration (NULL, TRUE);

      toplevel = find_toplevel_at_pointer (gdk_screen_get_display (screen));
      if (toplevel == popup)
        toplevel = NULL;
    }

  g_object_unref (cursor);
  gtk_widget_destroy (popup);
  gdk_flush ();                 /* Really release the grab */

  return toplevel;
}
示例#5
0
文件: gtktooltip.c 项目: aswinas/gtk-
void
_gtk_tooltip_focus_in (GtkWidget *widget)
{
  gint x, y;
  gboolean return_value = FALSE;
  GdkDisplay *display;
  GtkTooltip *tooltip;
  GdkDevice *device;

  /* Get current tooltip for this display */
  display = gtk_widget_get_display (widget);
  tooltip = g_object_get_data (G_OBJECT (display),
			       "gdk-display-current-tooltip");

  /* Check if keyboard mode is enabled at this moment */
  if (!tooltip || !tooltip->keyboard_mode_enabled)
    return;

  device = gtk_get_current_event_device ();

  if (device && gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
    device = gdk_device_get_associated_device (device);

  /* This function should be called by either a focus in event,
   * or a key binding. In either case there should be a device.
   */
  if (!device)
    return;

  if (tooltip->keyboard_widget)
    g_object_unref (tooltip->keyboard_widget);

  tooltip->keyboard_widget = g_object_ref (widget);

  gdk_window_get_device_position (gtk_widget_get_window (widget),
                                  device, &x, &y, NULL);

  return_value = gtk_tooltip_run_requery (&widget, tooltip, &x, &y);
  if (!return_value)
    {
      gtk_tooltip_hide_tooltip (tooltip);
      return;
    }

  if (!tooltip->current_window)
    {
      if (gtk_widget_get_tooltip_window (widget))
	tooltip->current_window = gtk_widget_get_tooltip_window (widget);
      else
	tooltip->current_window = GTK_WINDOW (GTK_TOOLTIP (tooltip)->window);
    }

  gtk_tooltip_show_tooltip (display);
}
示例#6
0
static void
photos_searchbar_default_show (PhotosSearchbar *self)
{
  PhotosSearchbarPrivate *priv = self->priv;
  GdkDevice *event_device;

  event_device = gtk_get_current_event_device ();
  gtk_revealer_set_reveal_child (GTK_REVEALER (self), TRUE);
  priv->in = TRUE;

  if (event_device != NULL)
    gd_entry_focus_hack (priv->search_entry, event_device);
}
/**
 * go_combo_popup_tear_off
 * @combo:         Combo box
 * @set_position:  Set to position of popup shell if true
 *
 * Tear off the popup
 *
 * FIXME:
 * Gtk popup menus are toplevel windows, not dialogs. I think this is wrong,
 * and make the popups dialogs. But may be there should be a way to make
 * them toplevel. We can do this after creating:
 * GTK_WINDOW (tearoff)->type = GTK_WINDOW_TOPLEVEL;
 */
static void
go_combo_popup_tear_off (GOComboBox *combo, gboolean set_position)
{
	int x, y;

	if (!combo->priv->tearoff_window) {
		GtkWidget *tearoff;
		gchar const *title;

		/* FIXME: made this a toplevel, not a dialog ! */
		tearoff = gtk_window_new (GTK_WINDOW_TOPLEVEL);
		g_object_ref_sink (tearoff);
		combo->priv->tearoff_window = tearoff;
		gtk_widget_set_app_paintable (tearoff, TRUE);
		g_signal_connect (tearoff, "key_press_event",
				  G_CALLBACK (cb_combo_keypress),
				  combo);
		gtk_widget_realize (tearoff);
		title = go_combo_box_get_title (combo);
		if (title)
			gdk_window_set_title (gtk_widget_get_window (tearoff), title);
		gtk_window_set_transient_for
			(GTK_WINDOW (tearoff),
			 GTK_WINDOW (gtk_widget_get_toplevel
				     GTK_WIDGET (combo)));
	}

	if (gtk_widget_get_visible (combo->priv->popup)) {
		gtk_widget_hide (combo->priv->toplevel);

		gtk_grab_remove (combo->priv->toplevel);
			gdk_device_ungrab (gtk_get_current_event_device (),
					   GDK_CURRENT_TIME);
	}

	go_combo_popup_reparent (combo->priv->popup,
				  combo->priv->tearoff_window, FALSE);

	/* It may have got confused about size */
	gtk_widget_queue_resize (GTK_WIDGET (combo->priv->popup));

	if (set_position) {
		go_combo_box_get_pos (combo, &x, &y);
		gtk_window_move (GTK_WINDOW (combo->priv->tearoff_window), x, y);
	}
	gtk_widget_show (GTK_WIDGET (combo->priv->popup));
	gtk_widget_show (combo->priv->tearoff_window);

}
示例#8
0
void
gtk_popup_button_popup (GtkPopupButton *popup_button)
{
	GdkDevice *device = gtk_get_current_event_device ();
	
	if (!device) {
		GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (popup_button));
		GdkDeviceManager *device_manager = gdk_display_get_device_manager (display);
		GList *devices = gdk_device_manager_list_devices (
				device_manager, GDK_DEVICE_TYPE_MASTER);
		device = devices->data;
		g_list_free (devices);
	}
	
	gtk_popup_button_popup_for_device (popup_button, device);
}
示例#9
0
static void on_pointer_press(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
    // Hide the volume scale
    hide_volume_scale();

    // Find the pointer device, if possible
    GdkDevice *device = gtk_get_current_event_device();
    if (device && gdk_device_get_source(device) == GDK_SOURCE_KEYBOARD)
        device = gdk_device_get_associated_device(device);
    if (!device) {
        g_printerr("Failed to find the pointer device\n");
        return;
    }

    // Ungrab it
    gdk_device_ungrab(device, GDK_CURRENT_TIME);
    gdk_flush();
}
/* protected */ void
go_combo_box_popup_display (GOComboBox *combo_box)
{
	int x, y;

	g_return_if_fail (GO_COMBO_BOX (combo_box) != NULL);
	g_return_if_fail (combo_box->priv->popdown_container != NULL);

	if (combo_box->priv->torn_off) {
		/* To give the illusion that tearoff still displays the
		 * popup, we copy the image in the popup window to the
		 * background. Thus, it won't be blank after reparenting */
		go_combo_tearoff_bg_copy (combo_box);

		/* We force an unrealize here so that we don't trigger
		 * redrawing/ clearing code - we just want to reveal our
		 * backing pixmap.
		 */
		go_combo_popup_reparent (combo_box->priv->popup,
					  combo_box->priv->toplevel, TRUE);
	}

	go_combo_box_get_pos (combo_box, &x, &y);

	gtk_window_move (GTK_WINDOW (combo_box->priv->toplevel), x, y);
	gtk_widget_realize (combo_box->priv->popup);
	gtk_widget_show (combo_box->priv->popup);
	gtk_widget_realize (combo_box->priv->toplevel);
	gtk_widget_show (combo_box->priv->toplevel);

	gtk_widget_grab_focus (combo_box->priv->toplevel);
	do_focus_change (combo_box->priv->toplevel, TRUE);

	gtk_grab_add (combo_box->priv->toplevel);
	gdk_device_grab (gtk_get_current_event_device (),
	                 gtk_widget_get_window (combo_box->priv->toplevel),
	                 GDK_OWNERSHIP_APPLICATION, TRUE,
			 GDK_BUTTON_PRESS_MASK |
			 GDK_BUTTON_RELEASE_MASK |
			 GDK_POINTER_MOTION_MASK,
			 NULL, GDK_CURRENT_TIME);
	set_arrow_state (combo_box, TRUE);
}
示例#11
0
文件: main.c 项目: eaglexmw/pnmixer
/**
 * Handles the 'activate' signal on the tray_icon,
 * usually opening the popup_window and grabbing pointer and keyboard.
 *
 * @param status_icon the object which received the signal
 * @param user_data user data set when the signal handler was connected
 */
void
tray_icon_on_click(G_GNUC_UNUSED GtkStatusIcon *status_icon,
		G_GNUC_UNUSED gpointer user_data)
{
	get_current_levels();
	if (!gtk_widget_get_visible(GTK_WIDGET(popup_window))) {
		gtk_widget_show_now(popup_window);
		gtk_widget_grab_focus(vol_scale);
#ifdef WITH_GTK3
		GdkDevice *pointer_dev = gtk_get_current_event_device();
		if (pointer_dev != NULL) {
			GdkDevice *keyboard_dev =
				gdk_device_get_associated_device(pointer_dev);
			if (gdk_device_grab(pointer_dev,
					    gtk_widget_get_window(GTK_WIDGET(popup_window)),
					    GDK_OWNERSHIP_NONE,
					    TRUE,
					    GDK_BUTTON_PRESS_MASK,
					    NULL, GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS)
				g_warning("Could not grab %s\n",
					  gdk_device_get_name(pointer_dev));
			if (keyboard_dev != NULL) {
				if (gdk_device_grab(keyboard_dev,
						    gtk_widget_get_window(GTK_WIDGET(popup_window)),
						    GDK_OWNERSHIP_NONE,
						    TRUE,
						    GDK_KEY_PRESS_MASK,
						    NULL, GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS)
					g_warning("Could not grab %s\n",
						  gdk_device_get_name(keyboard_dev));
			}
		}
#else
		gdk_keyboard_grab(gtk_widget_get_window(popup_window),
				  TRUE, GDK_CURRENT_TIME);
		gdk_pointer_grab(gtk_widget_get_window(popup_window), TRUE,
				 GDK_BUTTON_PRESS_MASK, NULL, NULL, GDK_CURRENT_TIME);
#endif
	} else {
		gtk_widget_hide(popup_window);
	}
}
示例#12
0
void show_volume_scale(GdkRectangle *rect_or_null)
{
    // Actually show the volume scale
    do_show_volume_scale(rect_or_null);

    // Find the pointer device, if possible
    GdkDevice *device = gtk_get_current_event_device();
    if (device && gdk_device_get_source(device) == GDK_SOURCE_KEYBOARD)
        device = gdk_device_get_associated_device(device);
    if (!device) {
        g_printerr("Failed to find the pointer device\n");
        return;
    }

    // Grab it so we can hide the scale when the user clicks outside it
    g_signal_connect_after(G_OBJECT(window), "button_press_event", G_CALLBACK(on_pointer_press), NULL);
    gdk_device_grab(device, gtk_widget_get_window(window), GDK_OWNERSHIP_NONE,
            TRUE, GDK_BUTTON_PRESS_MASK, NULL, GDK_CURRENT_TIME);
    gdk_flush();
}
示例#13
0
文件: main.c 项目: eaglexmw/pnmixer
/**
 * Hides the volume popup_window, connected via the signals
 * button-press-event, key-press-event and grab-broken-event.
 *
 * @param widget the object which received the signal
 * @param event the GdkEventButton which triggered the signal
 * @param user_data user data set when the signal handler was connected
 * @return TRUE to stop other handlers from being invoked for the evend,
 * FALSE to propagate the event further
 */
gboolean
hide_me(G_GNUC_UNUSED GtkWidget *widget,
		GdkEvent *event, G_GNUC_UNUSED gpointer user_data)
{
#ifdef WITH_GTK3
	GdkDevice *device = gtk_get_current_event_device();
#endif
	gint x, y;

	switch (event->type) {
	/* If a click happens outside of the popup, hide it */
	case GDK_BUTTON_PRESS:
		if (
#ifdef WITH_GTK3
			!gdk_device_get_window_at_position(device, &x, &y)
#else
			!gdk_window_at_pointer(&x, &y)
#endif
		)
			gtk_widget_hide(popup_window);
		break;

	/* If 'Esc' is pressed, hide popup */
	case GDK_KEY_PRESS:
		if (event->key.keyval == GDK_KEY_Escape) {
			gtk_widget_hide(popup_window);
		}
		break;

	/* Broken grab, hide popup */
	case GDK_GRAB_BROKEN:
		gtk_widget_hide(popup_window);
		break;

	/* Unhandle event, do nothing */
	default:
		break;
	}

	return FALSE;
}
示例#14
0
/* Finds the toplevel window under the mouse pointer, if any.
 */
static GtkWidget *
find_toplevel_at_pointer (GdkDisplay *display)
{
  GdkWindow *pointer_window;
  GtkWidget *widget = NULL;

  pointer_window = gdk_device_get_window_at_position (gtk_get_current_event_device (),
                                                      NULL, NULL);

  /* The user data field of a GdkWindow is used to store a pointer
   * to the widget that created it.
   */
  if (pointer_window)
    {
      gpointer widget_ptr;
      gdk_window_get_user_data (pointer_window, &widget_ptr);
      widget = widget_ptr;
    }

  return widget ? gtk_widget_get_toplevel (widget) : NULL;
}
示例#15
0
static void
grab_devices(GtkWidget *window)
{
	GdkGrabStatus status;
	GdkDevice *device;

	/* Grab the current event device */
	device = gtk_get_current_event_device();
	if (device == NULL) {
		WARN("Couldn't get current device");
                return;
	}

	/* Grab every seat capabilities */
	status = gdk_seat_grab(gdk_device_get_seat(device),
	                       gtk_widget_get_window(window),
	                       GDK_SEAT_CAPABILITY_ALL, TRUE,
	                       NULL, NULL, NULL, NULL);
	if (status != GDK_GRAB_SUCCESS)
		WARN("Could not grab %s", gdk_device_get_name(device));
}
示例#16
0
static void
grab_devices(GtkWidget *window)
{
	GdkDevice *pointer_dev;
	GdkDevice *keyboard_dev;
	GdkGrabStatus status;

	/* Grab the mouse */
	pointer_dev = gtk_get_current_event_device();
	if (pointer_dev == NULL) {
		WARN("Couldn't get current device");
                return;
	}

	status = gdk_device_grab(pointer_dev,
	                         gtk_widget_get_window(window),
	                         GDK_OWNERSHIP_NONE,
	                         TRUE,
	                         GDK_BUTTON_PRESS_MASK,
	                         NULL,
	                         GDK_CURRENT_TIME);
	if (status != GDK_GRAB_SUCCESS)
		WARN("Could not grab %s", gdk_device_get_name(pointer_dev));

	/* Grab the keyboard */
	keyboard_dev = gdk_device_get_associated_device(pointer_dev);
	if (keyboard_dev == NULL) {
		WARN("Couldn't get associated device");
                return;
        }

	status = gdk_device_grab(keyboard_dev,
	                         gtk_widget_get_window(window),
	                         GDK_OWNERSHIP_NONE,
	                         TRUE,
	                         GDK_KEY_PRESS_MASK,
	                         NULL, GDK_CURRENT_TIME);
	if (status != GDK_GRAB_SUCCESS)
		WARN("Could not grab %s", gdk_device_get_name(keyboard_dev));
}
示例#17
0
/**
 * Handles 'button-press-event', 'key-press-event' and 'grab-broken-event' signals,
 * on the GtkWindow. Used to hide the volume popup window.
 *
 * @param widget the object which received the signal.
 * @param event the GdkEvent which triggered this signal.
 * @param window user data set when the signal handler was connected.
 * @return TRUE to stop other handlers from being invoked for the event.
 * FALSE to propagate the event further.
 */
gboolean
on_popup_window_event(G_GNUC_UNUSED GtkWidget *widget, GdkEvent *event,
                      PopupWindow *window)
{
	switch (event->type) {

	/* If a click happens outside of the popup, hide it */
	case GDK_BUTTON_PRESS: {
		gint x, y;
#ifdef WITH_GTK3
		GdkDevice *device = gtk_get_current_event_device();

		if (!gdk_device_get_window_at_position(device, &x, &y))
#else
		if (!gdk_window_at_pointer(&x, &y))
#endif
			popup_window_hide(window);

		break;
	}

	/* If 'Esc' is pressed, hide popup */
	case GDK_KEY_PRESS:
		if (event->key.keyval == GDK_KEY_Escape)
			popup_window_hide(window);
		break;

	/* Broken grab, hide popup */
	case GDK_GRAB_BROKEN:
		popup_window_hide(window);
		break;

	/* Unhandle event, do nothing */
	default:
		break;
	}

	return FALSE;
}
示例#18
0
static void
gtk_real_button_activate (GtkButton *button)
{
  GtkWidget *widget = GTK_WIDGET (button);
  GtkButtonPrivate *priv = button->priv;
  GdkDevice *device;

  device = gtk_get_current_event_device ();

  if (device && gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
    device = gdk_device_get_associated_device (device);

  if (gtk_widget_get_realized (widget) && !priv->activate_timeout)
    {
      /* bgo#626336 - Only grab if we have a device (from an event), not if we
       * were activated programmatically when no event is available.
       */
      if (device && gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
	{
          if (gdk_seat_grab (gdk_device_get_seat (device), priv->event_window,
                             GDK_SEAT_CAPABILITY_KEYBOARD, TRUE,
                             NULL, NULL, NULL, NULL) == GDK_GRAB_SUCCESS)
            {
              gtk_device_grab_add (widget, device, TRUE);
              priv->grab_keyboard = device;
	    }
	}

      priv->activate_timeout = gdk_threads_add_timeout (ACTIVATE_TIMEOUT,
						button_activate_timeout,
						button);
      g_source_set_name_by_id (priv->activate_timeout, "[gtk+] button_activate_timeout");
      priv->button_down = TRUE;
      gtk_button_update_state (button);
    }
}
示例#19
0
文件: testsocket.c 项目: GYGit/gtk
static void
grab_window_toggled (GtkToggleButton *button,
		     GtkWidget       *widget)
{
  GdkDevice *device = gtk_get_current_event_device ();
  GdkSeat *seat = gdk_device_get_seat (device);

  if (gtk_toggle_button_get_active (button))
    {
      int status;

      status = gdk_seat_grab (seat, gtk_widget_get_window (widget),
                              GDK_SEAT_CAPABILITY_KEYBOARD,
                              FALSE, NULL, NULL, NULL, NULL);

      if (status != GDK_GRAB_SUCCESS)
	g_warning ("Could not grab keyboard!  (%s)", grab_string (status));

    }
  else
    {
      gdk_seat_ungrab (seat);
    }
}
示例#20
0
static void
gnc_date_edit_popup (GNCDateEdit *gde)
{
    GtkWidget *toplevel;
    struct tm mtm;
    gboolean date_was_valid;
    GdkDevice *device, *keyboard, *pointer;

    g_return_if_fail (GNC_IS_DATE_EDIT (gde));

    ENTER("gde %p", gde);

    device = gtk_get_current_event_device ();

    /* This code is pretty much just copied from gtk_date_edit_get_date */
    date_was_valid = qof_scan_date (gtk_entry_get_text (GTK_ENTRY (gde->date_entry)),
                                    &mtm.tm_mday, &mtm.tm_mon, &mtm.tm_year);
    if (!date_was_valid)
    {
        /* No valid date. Hacky workaround: Instead of crashing we randomly choose today's date. */
        gnc_tm_get_today_start(&mtm);
    }

    mtm.tm_mon--;

    /* Hope the user does not actually mean years early in the A.D. days...
     * This date widget will obviously not work for a history program :-)
     */
    if (mtm.tm_year >= 1900)
        mtm.tm_year -= 1900;

    gnc_tm_set_day_start(&mtm);

    /* Set the calendar.  */
    gtk_calendar_select_day (GTK_CALENDAR (gde->calendar), 1);
    gtk_calendar_select_month (GTK_CALENDAR (gde->calendar), mtm.tm_mon,
                               1900 + mtm.tm_year);
    gtk_calendar_select_day (GTK_CALENDAR (gde->calendar), mtm.tm_mday);

    /* Make sure we'll get notified of clicks outside the popup
     * window so we can properly pop down if that happens. */
    toplevel = gtk_widget_get_toplevel (GTK_WIDGET (gde));
    if (GTK_IS_WINDOW (toplevel))
    {
        gtk_window_group_add_window (
            gtk_window_get_group (GTK_WINDOW (toplevel)),
            GTK_WINDOW (gde->cal_popup));
        gtk_window_set_transient_for (GTK_WINDOW (gde->cal_popup),
                                      GTK_WINDOW (toplevel));
    }

    position_popup (gde);

    gtk_widget_show (gde->cal_popup);

    gtk_widget_grab_focus (gde->cal_popup);
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gde->date_button),
                                  TRUE);

    if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
    {
        keyboard = device;
        pointer = gdk_device_get_associated_device (device);
    }
    else
    {
        pointer = device;
        keyboard = gdk_device_get_associated_device (device);
    }

    if (!gtk_widget_has_focus (gde->calendar))
        gtk_widget_grab_focus (gde->calendar);

    if (!popup_grab_on_window (gtk_widget_get_window ((GTK_WIDGET(gde->cal_popup))),
                               keyboard, pointer, GDK_CURRENT_TIME))
    {
        gtk_widget_hide (gde->cal_popup);
        LEAVE("Failed to grab window");
        return;
    }

    gtk_grab_add (gde->cal_popup);

    LEAVE(" ");
}
示例#21
0
static gboolean on_auto_scroll(gpointer user_data)
{
    FmDndAutoScroll* as = (FmDndAutoScroll*)user_data;
    int x, y;
    GtkAdjustment* va = as->vadj;
    GtkAdjustment* ha = as->hadj;
    GtkWidget* widget = as->widget;
    GtkAllocation allocation;

    gdk_window_get_device_position (gtk_widget_get_window(widget),
                                    gtk_get_current_event_device(),
                                    &x, &y, NULL);
    gtk_widget_get_allocation(widget, &allocation);

    /*
       HACK.
       Sometimes we do not get drag-leave signal. (Why?)
       This check prevents infinite scrolling.
    */
    if (y < 0 || y > allocation.height ||
        x < 0 || x > allocation.width)
    {
        as->timeout = 0;
        return FALSE;
    }

    if(va)
    {
        if(y < SCROLL_EDGE_SIZE) /* scroll up */
        {
            gdouble value = gtk_adjustment_get_value(va);
            gdouble lower = gtk_adjustment_get_lower(va);
            if(value > lower)
            {
                value -= gtk_adjustment_get_step_increment(va);
                if(value < lower)
                    value = lower;
                gtk_adjustment_set_value(va, value);
            }
        }
        else if(y > (allocation.height - SCROLL_EDGE_SIZE))
        {
            gdouble value = gtk_adjustment_get_value(va);
            gdouble upper = gtk_adjustment_get_upper(va) - gtk_adjustment_get_page_size(va);
            /* scroll down */
            if(value < upper)
            {
                value += gtk_adjustment_get_step_increment(va);
                if(value > upper)
                    value = upper;
                gtk_adjustment_set_value(va, value);
            }
        }
        gtk_adjustment_value_changed(va);
    }

    if(ha)
    {
        if(x < SCROLL_EDGE_SIZE) /* scroll to left */
        {
            gdouble value = gtk_adjustment_get_value(ha);
            gdouble lower = gtk_adjustment_get_lower(ha);
            if(value > lower)
            {
                value -= gtk_adjustment_get_step_increment(ha);
                if(value < lower)
                    value = lower;
                gtk_adjustment_set_value(ha, value);
            }
        }
        else if(x > (allocation.width - SCROLL_EDGE_SIZE))
        {
            gdouble value = gtk_adjustment_get_value(ha);
            gdouble upper = gtk_adjustment_get_upper(ha) - gtk_adjustment_get_page_size(ha);
            /* scroll to right */
            if(value < upper)
            {
                value += gtk_adjustment_get_step_increment(ha);
                if(value > upper)
                    value = upper;
                gtk_adjustment_set_value(ha, value);
            }
        }
        gtk_adjustment_value_changed(ha);
    }
    return TRUE;
}
示例#22
0
/**
 * gnm_cell_combo_view_popdown:
 * @sov: #SheetObjectView
 * @activate_time: event time
 *
 * Open the popup window associated with @sov
 **/
void
gnm_cell_combo_view_popdown (SheetObjectView *sov, guint32 activate_time)
{
	GocItem		   *view   = GOC_ITEM (sov);
	GnmPane		   *pane   = GNM_PANE (view->canvas);
	SheetControlGUI	   *scg    = pane->simple.scg;
	SheetObject	   *so     = sheet_object_view_get_so (sov);
	Sheet const	   *sheet  = sheet_object_get_sheet (so);
	GtkWidget *frame,  *popup, *list, *container;
	int root_x, root_y;
	gboolean 	make_buttons = FALSE;
	GtkTreePath	  *clip = NULL, *select = NULL;
	GtkWindow *toplevel = wbcg_toplevel (scg_wbcg (scg));
	GdkWindow *popup_window;
	GdkDevice *device;
	GnmRange const *merge;

	popup = gtk_window_new (GTK_WINDOW_POPUP);

	gtk_window_set_type_hint (GTK_WINDOW (popup), GDK_WINDOW_TYPE_HINT_COMBO);
	gtk_window_group_add_window (gtk_window_get_group (toplevel), GTK_WINDOW (popup));
	go_gtk_window_set_transient (toplevel, GTK_WINDOW (popup));
	gtk_window_set_resizable (GTK_WINDOW (popup), FALSE);
	gtk_window_set_decorated (GTK_WINDOW (popup), FALSE);
	gtk_window_set_screen (GTK_WINDOW (popup),
		gtk_widget_get_screen (GTK_WIDGET (toplevel)));

	list = ccombo_create_list (GNM_CCOMBO_VIEW (sov), so, &clip, &select, &make_buttons);

	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list), FALSE);
	g_object_set_data (G_OBJECT (list), SOV_ID, sov);

	frame = gtk_frame_new (NULL);
	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);

#if 0
	range_dump (&so->anchor.cell_bound, "");
	g_printerr (" : so = %p, view = %p\n", so, view);
#endif
	if (clip != NULL) {
		GtkWidget *sw = gtk_scrolled_window_new (
			gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (list)),
			gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (list)));
		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
						GTK_POLICY_AUTOMATIC,
						GTK_POLICY_ALWAYS);
		g_object_set_data_full (G_OBJECT (list),
					"clip", clip,
					(GDestroyNotify)gtk_tree_path_free);

		gtk_container_add (GTK_CONTAINER (sw), list);

		/*
		 * Do the sizing in a realize handler as newer versions of
		 * gtk+ give us zero sizes until then.
		 */
		g_signal_connect_after (list, "realize",
					G_CALLBACK (cb_realize_treeview),
					sw);
		container = sw;
	} else
		container = list;

	if (make_buttons) {
		GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
		GtkWidget *hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);

		GtkWidget *button;
		button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
		g_signal_connect_swapped (button, "clicked",
			G_CALLBACK (cb_ccombo_cancel_button), list);
		gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 6);
		button = gtk_button_new_from_stock (GTK_STOCK_OK);
		g_signal_connect_swapped (button, "clicked",
			G_CALLBACK (cb_ccombo_ok_button), list);
		gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 6);

		gtk_box_pack_start (GTK_BOX (vbox), container, FALSE, TRUE, 6);
		gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 6);
		container = vbox;
	}

	gtk_container_add (GTK_CONTAINER (frame), container);

	/* do the popup */
	gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (pane)),
			       &root_x, &root_y);
	if (sheet->text_is_rtl) {
		GtkAllocation pa;
		gtk_widget_get_allocation (GTK_WIDGET (pane), &pa);
		root_x += pa.width;
		root_x -= scg_colrow_distance_get (scg, TRUE,
			pane->first.col,
			so->anchor.cell_bound.start.col + 1);
	} else
		root_x += scg_colrow_distance_get (scg, TRUE,
			pane->first.col,
			so->anchor.cell_bound.start.col);
	merge = gnm_sheet_merge_is_corner (sheet, &(so->anchor.cell_bound.start));
	gtk_window_move (GTK_WINDOW (popup), root_x,
		root_y + scg_colrow_distance_get
			 (scg, FALSE,
			  pane->first.row,
			  so->anchor.cell_bound.start.row +
			  ((merge == NULL) ? 1 : range_height (merge))));

	gtk_container_add (GTK_CONTAINER (popup), frame);

	g_signal_connect (popup, "key_press_event",
		G_CALLBACK (cb_ccombo_key_press), list);
	g_signal_connect (popup, "button_press_event",
		G_CALLBACK (cb_ccombo_button_press), list);
	g_signal_connect_after (popup, "button_release_event",
		G_CALLBACK (cb_ccombo_button_release), list);
	g_signal_connect (list, "motion_notify_event",
		G_CALLBACK (cb_ccombo_list_motion), list);
	g_signal_connect (list, "button_press_event",
		G_CALLBACK (cb_ccombo_list_button_press), popup);

	gtk_widget_show_all (popup);

	/* after we show the window setup the selection (showing the list
	 * clears the selection) */
	if (select != NULL) {
		gtk_tree_selection_select_path (
			gtk_tree_view_get_selection (GTK_TREE_VIEW (list)),
			select);
		gtk_tree_view_set_cursor (GTK_TREE_VIEW (list),
			select, NULL, FALSE);
		gtk_tree_path_free (select);
	}

	gtk_widget_grab_focus (popup);
	gtk_widget_grab_focus (GTK_WIDGET (list));
	ccombo_focus_change (GTK_WIDGET (list), TRUE);

	popup_window = gtk_widget_get_window (popup);

	device = gtk_get_current_event_device ();
	if (0 == gdk_device_grab (device, popup_window,
	                          GDK_OWNERSHIP_APPLICATION, TRUE,
	                          GDK_BUTTON_PRESS_MASK |
	                          GDK_BUTTON_RELEASE_MASK |
	                          GDK_POINTER_MOTION_MASK,
	                          NULL, activate_time)) {
		if (0 == gdk_device_grab (gdk_device_get_associated_device (device),
		                          popup_window,
		                          GDK_OWNERSHIP_APPLICATION, TRUE,
		                          GDK_KEY_PRESS_MASK |
		                          GDK_KEY_RELEASE_MASK,
		                          NULL, activate_time))
			gtk_grab_add (popup);
		else
			gdk_device_ungrab (device, activate_time);
	}
}
static void
emoticon_tool_button_popup (EEmoticonToolButton *button)
{
	GtkToggleToolButton *tool_button;
	GdkWindow *window;
	gboolean grab_status;
	GdkDevice *device, *mouse, *keyboard;
	guint32 activate_time;

	device = gtk_get_current_event_device ();
	g_return_if_fail (device != NULL);

	if (!gtk_widget_get_realized (GTK_WIDGET (button)))
		return;

	if (button->priv->popup_shown)
		return;

	activate_time = gtk_get_current_event_time ();
	if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) {
		keyboard = device;
		mouse = gdk_device_get_associated_device (device);
	} else {
		keyboard = gdk_device_get_associated_device (device);
		mouse = device;
	}

	/* Position the window over the button. */
	emoticon_tool_button_reposition_window (button);

	/* Show the pop-up. */
	gtk_widget_show (button->priv->window);
	gtk_widget_grab_focus (button->priv->window);

	/* Activate the tool button. */
	tool_button = GTK_TOGGLE_TOOL_BUTTON (button);
	gtk_toggle_tool_button_set_active (tool_button, TRUE);

	/* Try to grab the pointer and keyboard. */
	window = gtk_widget_get_window (button->priv->window);
	grab_status = !keyboard ||
		gdk_device_grab (
			keyboard, window,
			GDK_OWNERSHIP_WINDOW, TRUE,
			GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
			NULL, activate_time) == GDK_GRAB_SUCCESS;
	if (grab_status) {
		grab_status = !mouse ||
			gdk_device_grab (mouse, window,
				GDK_OWNERSHIP_WINDOW, TRUE,
				GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
				NULL, activate_time) == GDK_GRAB_SUCCESS;
		if (!grab_status && keyboard)
			gdk_device_ungrab (keyboard, activate_time);
	}

	if (grab_status) {
		gtk_device_grab_add (button->priv->window, mouse, TRUE);
		button->priv->grab_keyboard = keyboard;
		button->priv->grab_mouse = mouse;
	} else {
		gtk_widget_hide (button->priv->window);
	}
}