예제 #1
0
void ygtk_popup_window_popup (GtkWidget *widget, gint x, gint y, guint activate_time)
{
	ygtk_popup_window_frame_position (widget, &x, &y);

	gtk_grab_add (widget);
	gtk_window_move (GTK_WINDOW (widget), x, y);
	gtk_widget_grab_focus (widget);
	gtk_widget_show (widget);

	GdkWindow *window = gtk_widget_get_window (widget);
	GdkDisplay *display = gdk_window_get_display (window);
	GdkDeviceManager *device_manager = gdk_display_get_device_manager (display);
	GdkDevice *pointer = gdk_device_manager_get_client_pointer (device_manager);

	// grab this with your teeth
	if (gdk_device_grab (pointer, window, GDK_OWNERSHIP_NONE, TRUE,
	        GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
	        NULL, activate_time) == 0) {
				GdkDevice *keyboard;
				keyboard = gdk_device_get_associated_device (pointer);
                if (gdk_device_grab (keyboard, window, GDK_OWNERSHIP_NONE, TRUE,
					GDK_KEY_PRESS | GDK_KEY_RELEASE, NULL, activate_time) != 0)
					gdk_device_ungrab (pointer, activate_time);
	}
}
예제 #2
0
static void
remove_popup (GtkWidget *popup)
{
	GdkWindow        *root;
#if GTK_CHECK_VERSION (3, 0, 0)
	GdkDisplay       *display;
	GdkDevice        *pointer;
	GdkDevice        *keyboard;
	GdkDeviceManager *device_manager;
#endif

	root = gdk_screen_get_root_window (
			gtk_window_get_screen (GTK_WINDOW (popup)));
	gdk_window_remove_filter (root, (GdkFilterFunc) popup_filter, popup);

	gtk_widget_destroy (popup);

#if GTK_CHECK_VERSION (3, 0, 0)
	display = gdk_window_get_display (root);
	device_manager = gdk_display_get_device_manager (display);
	pointer = gdk_device_manager_get_client_pointer (device_manager);
	keyboard = gdk_device_get_associated_device (pointer);

	gdk_device_ungrab (pointer, GDK_CURRENT_TIME);
	gdk_device_ungrab (keyboard, GDK_CURRENT_TIME);
#else
	gdk_pointer_ungrab (GDK_CURRENT_TIME);
	gdk_keyboard_ungrab (GDK_CURRENT_TIME);
#endif
}
예제 #3
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);
    }
}
예제 #4
0
static gboolean
popup_grab_on_window (GtkWidget *widget, guint32 activate_time)
{
	GdkDeviceManager *manager;
	GdkDevice *pointer;
	GdkWindow *window;
	window = gtk_widget_get_window (widget);
	manager = gdk_display_get_device_manager (gtk_widget_get_display (widget));
	pointer = gdk_device_manager_get_client_pointer (manager);
        if (gdk_device_grab (pointer, window, GDK_OWNERSHIP_WINDOW, TRUE,
			     GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
			     GDK_POINTER_MOTION_MASK,
			     NULL, activate_time) == GDK_GRAB_SUCCESS) {
		GdkDevice *keyb;
		keyb = gdk_device_get_associated_device (pointer);
                if (gdk_device_grab (keyb, window, GDK_OWNERSHIP_WINDOW, TRUE,
				     GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK, NULL, activate_time) ==
		    GDK_GRAB_SUCCESS)
                         return TRUE;
                 else {
                        gdk_device_ungrab (pointer, activate_time);
			return FALSE;
		 }
        }
        return FALSE;
}
예제 #5
0
// http://permalink.gmane.org/gmane.comp.gnome.svn/520942
void XAP_gdk_keyboard_ungrab(guint32 t)
{
	GdkDeviceManager *manager
		= gdk_display_get_device_manager(gdk_display_get_default());
	GdkDevice *device = gdk_device_manager_get_client_pointer (manager);
	gdk_device_ungrab (gdk_device_get_associated_device(device),
			   t);
}
예제 #6
0
파일: marco-mag.c 프로젝트: muesli4/marco
static void
shutdown_grab (void)
{
  GdkDeviceManager *manager = gdk_display_get_device_manager (gdk_display_get_default ());
  GdkDevice *device = gdk_device_manager_get_client_pointer (manager);

  gdk_device_ungrab (device, gtk_get_current_event_time ());
  gdk_device_ungrab (gdk_device_get_associated_device (device), gtk_get_current_event_time ());
  gtk_grab_remove (grab_widget);
}
예제 #7
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);
}
예제 #8
0
파일: marco-mag.c 프로젝트: muesli4/marco
static void
begin_area_grab (void)
{
  GdkWindow *window;
  GdkDeviceManager *manager;
  GdkDevice *device;

  if (grab_widget == NULL)
    {
      grab_widget = gtk_invisible_new ();

      gtk_widget_add_events (grab_widget,
                             GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);

      gtk_widget_show (grab_widget);
    }

  window = gtk_widget_get_window (grab_widget);
  manager = gdk_display_get_device_manager (gdk_display_get_default ());
  device = gdk_device_manager_get_client_pointer (manager);

  if (gdk_device_grab (device,
                       window,
                       GDK_OWNERSHIP_NONE,
                       FALSE,
                       GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK,
                       NULL,
                       gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
    {
      g_warning ("Failed to grab pointer to do eyedropper");
      return;
    }

  if (gdk_device_grab (gdk_device_get_associated_device (device),
                       window,
                       GDK_OWNERSHIP_NONE,
                       FALSE,
                       GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
                       NULL,
                       gtk_get_current_event_time ()) != GDK_GRAB_SUCCESS)
    {
      gdk_device_ungrab (device, gtk_get_current_event_time ());
      g_warning ("Failed to grab keyboard to do eyedropper");
      return;
    }

  gtk_grab_add (grab_widget);

  g_signal_connect (grab_widget, "button_press_event",
                    G_CALLBACK (mouse_press), NULL);
  g_signal_connect (grab_widget, "key_press_event",
                    G_CALLBACK (key_press), NULL);
}
예제 #9
0
GdkEventKey *
ide_gdk_synthesize_event_keyval (GdkWindow *window,
                                 guint      keyval)
{
  GdkDisplay *display;
  GdkDeviceManager *device_manager;
  GdkDevice *client_pointer;
  GdkEvent *ev;
  GdkKeymapKey *keys = NULL;
  gint n_keys = 0;
  gchar str[8] = { 0 };
  gunichar ch;

  g_assert (window != NULL);
  g_assert (GDK_IS_WINDOW (window));

  ch = gdk_keyval_to_unicode (keyval);
  g_unichar_to_utf8 (ch, str);

  ev = gdk_event_new (GDK_KEY_PRESS);
  ev->key.window = g_object_ref (window);
  ev->key.send_event = TRUE;
  ev->key.time = gtk_get_current_event_time ();
  ev->key.state = 0;
  ev->key.hardware_keycode = 0;
  ev->key.group = 0;
  ev->key.is_modifier = 0;
  ev->key.keyval = keyval;
  ev->key.string = g_strdup (str);
  ev->key.length = strlen (str);

  gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
                                     ev->key.keyval,
                                     &keys,
                                     &n_keys);

  if (n_keys > 0)
    {
      ev->key.hardware_keycode = keys [0].keycode;
      ev->key.group = keys [0].group;
      if (keys [0].level == 1)
        ev->key.state |= GDK_SHIFT_MASK;
      g_free (keys);
    }

  display = gdk_window_get_display (ev->any.window);
  device_manager = gdk_display_get_device_manager (display);
  client_pointer = gdk_device_manager_get_client_pointer (device_manager);
  gdk_event_set_device (ev, gdk_device_get_associated_device (client_pointer));

  return &ev->key;
}
예제 #10
0
void
panel_force_quit (GdkScreen *screen,
                  guint      time)
{
    GdkGrabStatus  status;
    GdkCursor     *cross;
    GtkWidget     *popup;
    GdkWindow     *root;
    GdkDisplay    *display;
    GdkDevice     *pointer;
    GdkDevice     *keyboard;
    GdkDeviceManager *device_manager;

    popup = display_popup_window (screen);

    root = gdk_screen_get_root_window (screen);

    gdk_window_add_filter (root, (GdkFilterFunc) popup_filter, popup);

    cross = gdk_cursor_new (GDK_CROSS);

    display = gdk_window_get_display (root);
    device_manager = gdk_display_get_device_manager (display);
    pointer = gdk_device_manager_get_client_pointer (device_manager);
    keyboard = gdk_device_get_associated_device (pointer);

    status = gdk_device_grab (pointer, root,
                              GDK_OWNERSHIP_NONE, FALSE,
                              GDK_BUTTON_PRESS_MASK,
                              cross, time);

    g_object_unref (cross);

    if (status != GDK_GRAB_SUCCESS) {
        g_warning ("Pointer grab failed\n");
        remove_popup (popup);
        return;
    }

    status = gdk_device_grab (keyboard, root,
                              GDK_OWNERSHIP_NONE, FALSE,
                              GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
                              NULL, time);
    if (status != GDK_GRAB_SUCCESS) {
        g_warning ("Keyboard grab failed\n");
        remove_popup (popup);
        return;
    }

    gdk_flush ();
}
예제 #11
0
/*
 * gtk_bubble_window_grab:
 * @window: a #GtkBubbleWindow
 * @device: a master #GdkDevice
 * @activate_time: timestamp to perform the grab
 *
 * This function performs GDK and GTK+ grabs on @device and
 * its paired #GdkDevice. After this call all pointer/keyboard
 * events will be handled by @window.
 *
 * Calling this also brings in a #GtkMenu alike behavior, clicking
 * outside the #GtkBubbleWindow or pressing the Escape key will
 * popdown the menu by default.
 *
 * <note>
 *   If there was a previous grab, it will be undone before doing
 *   the requested grab.
 * </note>
 *
 * Returns: %TRUE if the grab was successful
 *
 * Since: 3.8
 */
gboolean
_gtk_bubble_window_grab (GtkBubbleWindow *window,
                         GdkDevice       *device,
                         guint32          activate_time)
{
  GtkBubbleWindowPrivate *priv;
  GdkDevice *other_device;
  GdkWindow *grab_window;
  GdkGrabStatus status;

  g_return_val_if_fail (GTK_IS_BUBBLE_WINDOW (window), FALSE);
  g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
  g_return_val_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER, FALSE);

  priv = window->priv;

  if (!priv->has_pointing_to ||
      gdk_window_is_destroyed (priv->relative_to))
    return FALSE;

  if (priv->device)
    _gtk_bubble_window_ungrab (window);

  gtk_widget_realize (GTK_WIDGET (window));
  grab_window = gtk_widget_get_window (GTK_WIDGET (window));
  other_device = gdk_device_get_associated_device (device);

  status = gdk_device_grab (device, grab_window,
                            GDK_OWNERSHIP_WINDOW, TRUE, GRAB_EVENT_MASK,
                            NULL, activate_time);

  if (status == GDK_GRAB_SUCCESS)
    {
      status = gdk_device_grab (other_device, grab_window,
                                GDK_OWNERSHIP_WINDOW, TRUE, GRAB_EVENT_MASK,
                                NULL, activate_time);

      /* Ungrab the first device on error */
      if (status != GDK_GRAB_SUCCESS)
        gdk_device_ungrab (device, activate_time);
    }

  if (status == GDK_GRAB_SUCCESS)
    {
      gtk_device_grab_add (GTK_WIDGET (window), device, TRUE);
      priv->device = device;
    }

  return status == GDK_GRAB_SUCCESS;
}
예제 #12
0
파일: marco-mag.c 프로젝트: BrotherAl/marco
static void
shutdown_grab (void)
{
#if GTK_CHECK_VERSION (3, 0, 0)
  GdkDeviceManager *manager = gdk_display_get_device_manager (gdk_display_get_default ());
  GdkDevice *device = gdk_device_manager_get_client_pointer (manager);

  gdk_device_ungrab (device, gtk_get_current_event_time ());
  gdk_device_ungrab (gdk_device_get_associated_device (device), gtk_get_current_event_time ());
#else
  gdk_keyboard_ungrab (gtk_get_current_event_time ());
  gdk_pointer_ungrab (gtk_get_current_event_time ());
#endif
  gtk_grab_remove (grab_widget);
}
예제 #13
0
// Now onto the device were the deprecated functions are to be
// with several line of code.
GdkGrabStatus XAP_gdk_keyboard_grab(GdkWindow *window,
				    gboolean owner_events,
				    guint32 time_)
{
	GdkDeviceManager *manager
		= gdk_display_get_device_manager(gdk_display_get_default());
	GdkDevice *device = gdk_device_manager_get_client_pointer (manager);

	return gdk_device_grab (gdk_device_get_associated_device(device),
				window,
				GDK_OWNERSHIP_WINDOW,
				owner_events,
				GDK_ALL_EVENTS_MASK,
				NULL,
				time_);
}
예제 #14
0
static gboolean
gtk_bubble_window_grab_broken (GtkWidget          *widget,
                               GdkEventGrabBroken *grab_broken)
{
  GtkBubbleWindow *window = GTK_BUBBLE_WINDOW (widget);
  GtkBubbleWindowPrivate *priv;
  GdkDevice *event_device;

  priv = window->priv;
  event_device = gdk_event_get_device ((GdkEvent *) grab_broken);

  if (event_device == priv->device ||
      event_device == gdk_device_get_associated_device (priv->device))
    _gtk_bubble_window_ungrab (window);

  return FALSE;
}
static ClutterInputDevice *
clutter_device_manager_gdk_get_core_device (ClutterDeviceManager   *manager,
                                            ClutterInputDeviceType  device_type)
{
  ClutterDeviceManagerGdk *manager_gdk = CLUTTER_DEVICE_MANAGER_GDK (manager);
  GdkDevice *gdk_device;

  gdk_device = gdk_device_manager_get_client_pointer (manager_gdk->device_manager);

  g_assert (gdk_device != NULL);

  if (device_type == CLUTTER_KEYBOARD_DEVICE)
    gdk_device = gdk_device_get_associated_device (gdk_device);
  else if (device_type != CLUTTER_POINTER_DEVICE)
    return NULL;

  return _clutter_device_manager_gdk_lookup_device (manager, gdk_device);
}
예제 #16
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();
}
예제 #17
0
/*
 * gtk_bubble_window_ungrab:
 * @window: a #GtkBubbleWindow
 *
 * This functions undoes a grab added through gtk_bubble_window_grab()
 * in this @window,
 *
 * Since: 3.8
 */
void
_gtk_bubble_window_ungrab (GtkBubbleWindow *window)
{
  GtkBubbleWindowPrivate *priv;

  g_return_if_fail (GTK_IS_BUBBLE_WINDOW (window));

  priv = window->priv;

  if (!priv->device)
    return;

  gdk_device_ungrab (priv->device, GDK_CURRENT_TIME);
  gdk_device_ungrab (gdk_device_get_associated_device (priv->device),
                     GDK_CURRENT_TIME);
  gtk_device_grab_remove (GTK_WIDGET (window), priv->device);
  priv->device = NULL;
}
예제 #18
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);
	}
}
예제 #19
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();
}
예제 #20
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));
}
예제 #21
0
static gboolean
property_query_event (GtkWidget *widget,
                      GdkEvent  *event,
                      gpointer   data)
{
  GtkInspectorWindow *iw = (GtkInspectorWindow *)data;

  if (event->type == GDK_BUTTON_RELEASE)
    {
      g_signal_handlers_disconnect_by_func (widget, property_query_event, data);
      gtk_grab_remove (widget);
      gdk_device_ungrab (gdk_event_get_device (event), GDK_CURRENT_TIME);
      on_inspect_widget (widget, event, data);
    }
  else if (event->type == GDK_MOTION_NOTIFY)
    {
      on_highlight_widget (widget, event, data);
    }
  else if (event->type == GDK_KEY_PRESS)
    {
      GdkEventKey *ke = (GdkEventKey*)event;
      GdkDevice *device;

      if (ke->keyval == GDK_KEY_Escape)
        {
          g_signal_handlers_disconnect_by_func (widget, property_query_event, data);
          gtk_grab_remove (widget);
          device = gdk_device_get_associated_device (gdk_event_get_device (event));
          gdk_device_ungrab (device, GDK_CURRENT_TIME);
          gdk_window_raise (gtk_widget_get_window (GTK_WIDGET (iw)));
          clear_flash (iw);
        }
    }

  return TRUE;
}
예제 #22
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);
    }
}
예제 #23
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);
	}
}
예제 #24
0
static void
gtk_popup_button_popup_real (GtkPopupButton *popup_button, GdkDevice *device)
{
	GtkPopupButtonPrivate *priv = popup_button->priv;
	GtkAllocation button_allocation, dock_allocation;
	GdkScreen *screen;
	gint monitor_num;
	GdkRectangle monitor;
	GtkWidget *toplevel;
	GdkDevice *keyboard, *pointer;
	guint32 time;
	gint x, y;
	
	g_return_if_fail (GTK_IS_POPUP_BUTTON (popup_button));
	g_return_if_fail (GDK_IS_DEVICE (device));
	
	if (!gtk_widget_get_realized (GTK_WIDGET (popup_button)))
		return;
	
	if (gtk_widget_get_mapped (priv->dock))
		return;
	
	if (priv->grab_pointer && priv->grab_keyboard)
		return;
	
	time = gtk_get_current_event_time ();
	
	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);
	}
	
	toplevel = gtk_widget_get_toplevel (GTK_WIDGET (popup_button));
	if (GTK_IS_WINDOW (toplevel))
		gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (toplevel)),
				GTK_WINDOW (priv->dock));
	
	/* positioning */
	gtk_widget_show (priv->dock);
	gtk_widget_get_allocation (GTK_WIDGET (popup_button), &button_allocation);
	gdk_window_get_root_coords (gtk_widget_get_window (GTK_WIDGET (popup_button)),
			button_allocation.x, button_allocation.y, &x, &y);
	gtk_widget_get_allocation (GTK_WIDGET (priv->dock), &dock_allocation);
	
	x = (x + button_allocation.width / 2) - (dock_allocation.width / 2);
	y = y - dock_allocation.height;
	
	GdkWindow *window = window = gtk_widget_get_window (GTK_WIDGET (popup_button));
	screen = gtk_widget_get_screen (GTK_WIDGET (priv->dock));
	monitor_num = gdk_screen_get_monitor_at_window (screen, window);
	gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
	
	if (x < monitor.x)
		x = monitor.x;
	else if (x + dock_allocation.width > monitor.x + monitor.width)
		x = monitor.x + monitor.width - dock_allocation.width;
	
	gtk_window_move (GTK_WINDOW (priv->dock), x, y);
	
	/* grabbing */
	gtk_widget_grab_focus (priv->dock);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (popup_button), TRUE);
	
	if (gdk_device_grab (pointer, gtk_widget_get_window (priv->dock),
			GDK_OWNERSHIP_WINDOW, TRUE,
			GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
			NULL, time) != GDK_GRAB_SUCCESS) {
		gtk_device_grab_remove (priv->dock, pointer);
		gtk_widget_hide (priv->dock);
		return;
	}
	
	if (gdk_device_grab (keyboard, gtk_widget_get_window (priv->dock),
			GDK_OWNERSHIP_WINDOW, TRUE,
			GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
			NULL, time) != GDK_GRAB_SUCCESS) {
		gdk_device_ungrab (pointer, time);
		gtk_device_grab_remove (priv->dock, pointer);
		gtk_widget_hide (priv->dock);
		return;
	}
	
	gtk_device_grab_add (priv->dock, pointer, TRUE);
	priv->grab_pointer = pointer;
	priv->grab_keyboard = keyboard;
}
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);
	}
}
예제 #26
0
void setup_input_devices (GromitData *data)
{
    /* ungrab all */
    release_grab (data, NULL);

    /* and clear our own device data list */
    GHashTableIter it;
    gpointer value;
    g_hash_table_iter_init (&it, data->devdatatable);
    while (g_hash_table_iter_next (&it, NULL, &value))
        g_free(value);
    g_hash_table_remove_all(data->devdatatable);


    /* get devices */
    GdkDeviceManager *device_manager = gdk_display_get_device_manager(data->display);
    GList *devices, *d;
    int i = 0;

    devices = g_list_concat(gdk_device_manager_list_devices
                            (device_manager, GDK_DEVICE_TYPE_MASTER),
                            gdk_device_manager_list_devices
                            (device_manager, GDK_DEVICE_TYPE_SLAVE));
    for(d = devices; d; d = d->next)
    {
        GdkDevice *device = (GdkDevice *) d->data;

        /* only enable devices with 2 ore more axes */
        if (gdk_device_get_source(device) != GDK_SOURCE_KEYBOARD && gdk_device_get_n_axes(device) >= 2)
        {
            gdk_device_set_mode (device, GDK_MODE_SCREEN);

            GromitDeviceData *devdata;

            devdata  = g_malloc0(sizeof (GromitDeviceData));
            devdata->device = device;
            devdata->index = i;

            /* get attached keyboard and grab the hotkey */
            if (!data->hot_keycode)
            {
                g_printerr("ERROR: Grabbing hotkey from attached keyboard "
                           "of '%s' failed, no hotkey defined.\n",
                           gdk_device_get_name(device));
                g_free(devdata);
                continue;
            }

            /* if this is a slave device, we need the master */
            GdkDevice *kdevice=device;
            if(gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_SLAVE)
                kdevice=gdk_device_get_associated_device (device);

            gint dev_id = -1;
            g_object_get(kdevice, "device-id", &dev_id, NULL);

            gint kbd_dev_id = -1;
            XIDeviceInfo* devinfo;
            int devicecount = 0;

            devinfo = XIQueryDevice(GDK_DISPLAY_XDISPLAY(data->display),
                                    dev_id,
                                    &devicecount);
            if(devicecount)
                kbd_dev_id = devinfo->attachment;
            XIFreeDeviceInfo(devinfo);

            if(kbd_dev_id != -1)
            {
                if(data->debug)
                    g_printerr("DEBUG: Grabbing hotkey from keyboard '%d' .\n", kbd_dev_id);

                XIEventMask mask;
                unsigned char bits[4] = {0,0,0,0};
                mask.mask = bits;
                mask.mask_len = sizeof(bits);

                XISetMask(bits, XI_KeyPress);
                XISetMask(bits, XI_KeyRelease);

                XIGrabModifiers modifiers[] = {{XIAnyModifier, 0}};
                int nmods = 1;

                gdk_error_trap_push ();

                XIGrabKeycode( GDK_DISPLAY_XDISPLAY(data->display),
                               kbd_dev_id,
                               data->hot_keycode,
                               GDK_WINDOW_XID(data->root),
                               GrabModeAsync,
                               GrabModeAsync,
                               True,
                               &mask,
                               nmods,
                               modifiers);

                XSync(GDK_DISPLAY_XDISPLAY(data->display), False);
                if(gdk_error_trap_pop())
                {
                    g_printerr("ERROR: Grabbing hotkey from keyboard device %d failed.\n",
                               kbd_dev_id);
                    g_free(devdata);
                    continue;
                }
            }

            g_hash_table_insert(data->devdatatable, device, devdata);
            g_printerr ("Enabled Device %d: \"%s\", (Type: %d)\n",
                        i++, gdk_device_get_name(device), gdk_device_get_source(device));
        }
    }

    g_printerr ("Now %d enabled devices.\n", g_hash_table_size(data->devdatatable));
}
예제 #27
0
/* This is a _horrible_ hack to have this here. This needs to be added to the
 * GTK+ menuing code in some manner.
 */
static void
drag_end_menu_cb (GtkWidget *widget, GdkDragContext     *context)
{
  GtkWidget *xgrab_shell;
  GtkWidget *parent;

  /* Find the last viewable ancestor, and make an X grab on it
   */
  parent = gtk_widget_get_parent (widget);
  xgrab_shell = NULL;

  /* FIXME: workaround for a possible gtk+ bug
   *    See bugs #92085(gtk+) and #91184(panel) for details.
   */
  g_object_set (widget, "has-tooltip", TRUE, NULL);

  while (parent)
    {
      gboolean viewable = TRUE;
      GtkWidget *tmp = parent;

      while (tmp)
	{
	  if (!gtk_widget_get_mapped (tmp))
	    {
	      viewable = FALSE;
	      break;
	    }
	  tmp = gtk_widget_get_parent (tmp);
	}

      if (viewable)
	xgrab_shell = parent;

#if GTK_CHECK_VERSION (3, 0, 0)
      parent = gtk_menu_shell_get_parent_shell (GTK_MENU_SHELL (parent));
#else
      parent = GTK_MENU_SHELL (parent)->parent_menu_shell;
#endif
    }

#if GTK_CHECK_VERSION (3, 0, 0)
  if (xgrab_shell)
#else
  if (xgrab_shell && !gtk_menu_get_tearoff_state (GTK_MENU(xgrab_shell)))
#endif
    {
#if GTK_CHECK_VERSION (3, 0, 0)
      gboolean status;
      GdkDisplay *display;
      GdkDevice *pointer;
      GdkDevice *keyboard;
#if GTK_CHECK_VERSION(3, 20, 0)
      GdkSeat *seat;
#else
      GdkDeviceManager *device_manager;
#endif
#endif
      GdkWindow *window = gtk_widget_get_window (xgrab_shell);
      GdkCursor *cursor = gdk_cursor_new_for_display (gdk_display_get_default (),
                                                      GDK_ARROW);

#if GTK_CHECK_VERSION (3, 0, 0)
      display = gdk_window_get_display (window);
#if GTK_CHECK_VERSION(3, 20, 0)
      seat = gdk_display_get_default_seat (display);
      pointer = gdk_seat_get_pointer (seat);
#else
      device_manager = gdk_display_get_device_manager (display);
      pointer = gdk_device_manager_get_client_pointer (device_manager);
#endif
      keyboard = gdk_device_get_associated_device (pointer);

      /* FIXMEgpoo: Not sure if report to GDK_OWNERSHIP_WINDOW
         or GDK_OWNERSHIP_APPLICATION Idem for the
         keyboard below */
      status = gdk_device_grab (pointer, window,
                                GDK_OWNERSHIP_WINDOW, TRUE,
                                GDK_BUTTON_PRESS_MASK
                                | GDK_BUTTON_RELEASE_MASK
                                | GDK_ENTER_NOTIFY_MASK
                                | GDK_LEAVE_NOTIFY_MASK
                                | GDK_POINTER_MOTION_MASK,
                                cursor, GDK_CURRENT_TIME);

      if (!status)
        {
	  if (gdk_device_grab (keyboard, window,
			       GDK_OWNERSHIP_WINDOW, TRUE,
			       GDK_KEY_PRESS | GDK_KEY_RELEASE,
			       NULL, GDK_CURRENT_TIME) == GDK_GRAB_SUCCESS)
	    {
#else
      if ((gdk_pointer_grab (window, TRUE,
			     GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
			     GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
			     GDK_POINTER_MOTION_MASK,
			     NULL, cursor, GDK_CURRENT_TIME) == 0))
	{
	  if (gdk_keyboard_grab (window, TRUE,
				 GDK_CURRENT_TIME) == 0)
	    {
#endif
/* FIXME fix for GTK3 */
#if !GTK_CHECK_VERSION (3, 0, 0)
          GTK_MENU_SHELL (xgrab_shell)->have_xgrab = TRUE;
#endif
	    }
	  else
	    {
#if GTK_CHECK_VERSION (3, 0, 0)
	      gdk_device_ungrab (pointer, GDK_CURRENT_TIME);
	    }
	}

      g_object_unref (cursor);
#else
	      gdk_pointer_ungrab (GDK_CURRENT_TIME);
	    }
	}

      gdk_cursor_unref (cursor);
#endif
    }
}
static void
screenshot_select_area_x11_async (CallbackData *cb_data)
{
  GdkCursor *cursor;
  select_area_filter_data  data;
  GdkDeviceManager *manager;
  GdkDevice *pointer, *keyboard;
  GdkGrabStatus res;

  data.rect.x = 0;
  data.rect.y = 0;
  data.rect.width  = 0;
  data.rect.height = 0;
  data.button_pressed = FALSE;
  data.aborted = FALSE;
  data.window = create_select_window();

  g_signal_connect (data.window, "key-press-event", G_CALLBACK (select_area_key_press), &data);
  g_signal_connect (data.window, "button-press-event", G_CALLBACK (select_area_button_press), &data);
  g_signal_connect (data.window, "button-release-event", G_CALLBACK (select_area_button_release), &data);
  g_signal_connect (data.window, "motion-notify-event", G_CALLBACK (select_area_motion_notify), &data);

  cursor = gdk_cursor_new (GDK_CROSSHAIR);
  manager = gdk_display_get_device_manager (gdk_display_get_default ());
  pointer = gdk_device_manager_get_client_pointer (manager);
  keyboard = gdk_device_get_associated_device (pointer);

  res = gdk_device_grab (pointer, gtk_widget_get_window (data.window),
                         GDK_OWNERSHIP_NONE, FALSE,
                         GDK_POINTER_MOTION_MASK |
                         GDK_BUTTON_PRESS_MASK | 
                         GDK_BUTTON_RELEASE_MASK,
                         cursor, GDK_CURRENT_TIME);

  if (res != GDK_GRAB_SUCCESS)
    {
      g_object_unref (cursor);
      goto out;
    }

  res = gdk_device_grab (keyboard, gtk_widget_get_window (data.window),
                         GDK_OWNERSHIP_NONE, FALSE,
                         GDK_KEY_PRESS_MASK |
                         GDK_KEY_RELEASE_MASK,
                         NULL, GDK_CURRENT_TIME);
  if (res != GDK_GRAB_SUCCESS)
    {
      gdk_device_ungrab (pointer, GDK_CURRENT_TIME);
      g_object_unref (cursor);
      goto out;
    }

  gtk_main ();

  gdk_device_ungrab (pointer, GDK_CURRENT_TIME);
  gdk_device_ungrab (keyboard, GDK_CURRENT_TIME);

  gtk_widget_destroy (data.window);
  g_object_unref (cursor);

  gdk_flush ();

 out:
  cb_data->aborted = data.aborted;
  cb_data->rectangle = data.rect;

  /* FIXME: we should actually be emitting the callback When
   * the compositor has finished re-drawing, but there seems to be no easy
   * way to know that.
   */
  g_timeout_add (200, emit_select_callback_in_idle, cb_data);
}
예제 #29
0
/* This is a _horrible_ hack to have this here. This needs to be added to the
 * GTK+ menuing code in some manner.
 */
static void  
drag_end_menu_cb (GtkWidget *widget, GdkDragContext     *context)
{
  GtkWidget *xgrab_shell;
  GtkWidget *parent;

  /* Find the last viewable ancestor, and make an X grab on it
   */
  parent = gtk_widget_get_parent (widget);
  xgrab_shell = NULL;

  /* FIXME: workaround for a possible gtk+ bug
   *    See bugs #92085(gtk+) and #91184(panel) for details.
   */
  g_object_set (widget, "has-tooltip", TRUE, NULL);

  while (parent)
    {
      gboolean viewable = TRUE;
      GtkWidget *tmp = parent;
      
      while (tmp)
	{
	  if (!gtk_widget_get_mapped (tmp))
	    {
	      viewable = FALSE;
	      break;
	    }
	  tmp = gtk_widget_get_parent (tmp);
	}
      
      if (viewable)
	xgrab_shell = parent;
      
      parent = gtk_menu_shell_get_parent_shell (GTK_MENU_SHELL (parent));
    }

  if (xgrab_shell)
    {
      gboolean      status;
      GdkDisplay    *display;
      GdkDevice     *pointer;
      GdkDevice     *keyboard;
      GdkDeviceManager *device_manager;
      GdkWindow *window = gtk_widget_get_window (xgrab_shell);
      GdkCursor *cursor = gdk_cursor_new_for_display (gdk_display_get_default (),
                                                      GDK_ARROW);

      display = gdk_window_get_display (window);
      device_manager = gdk_display_get_device_manager (display);
      pointer = gdk_device_manager_get_client_pointer (device_manager);
      keyboard = gdk_device_get_associated_device (pointer);

      /* FIXMEgpoo: Not sure if report to GDK_OWNERSHIP_WINDOW
	            or GDK_OWNERSHIP_APPLICATION. Idem for the
                    keyboard below */
      status = gdk_device_grab (pointer, window,
                                GDK_OWNERSHIP_WINDOW, TRUE,
                                GDK_BUTTON_PRESS_MASK
                                | GDK_BUTTON_RELEASE_MASK
                                | GDK_ENTER_NOTIFY_MASK
                                | GDK_LEAVE_NOTIFY_MASK
                                | GDK_POINTER_MOTION_MASK,
                                cursor, GDK_CURRENT_TIME);

      if (!status)
	{
	  if (gdk_device_grab (keyboard, window,
			       GDK_OWNERSHIP_WINDOW, TRUE,
			       GDK_KEY_PRESS | GDK_KEY_RELEASE,
			       NULL, GDK_CURRENT_TIME) == GDK_GRAB_SUCCESS)
	    {
	    /* FIXMEgpoo: We need either accessors or a workaround to grab
	       the focus */
#if 0
	     GTK_MENU_SHELL (xgrab_shell)->GSEAL(have_xgrab) = TRUE;
#endif
	    }
	  else
	    {
	      gdk_device_ungrab (pointer, GDK_CURRENT_TIME);
	    }
	}

      g_object_unref (cursor);
    }
}
예제 #30
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(" ");
}