/* FIXME remove when gtknotebook's func for this becomes public, bug #.... */ static NautilusNotebook * find_notebook_at_pointer (gint abs_x, gint abs_y) { GdkDeviceManager *manager; GdkDevice *pointer; GdkWindow *win_at_pointer, *toplevel_win; gpointer toplevel = NULL; gint x, y; /* FIXME multi-head */ manager = gdk_display_get_device_manager (gdk_display_get_default ()); pointer = gdk_device_manager_get_client_pointer (manager); win_at_pointer = gdk_device_get_window_at_position (pointer, &x, &y); if (win_at_pointer == NULL) { /* We are outside all windows containing a notebook */ return NULL; } toplevel_win = gdk_window_get_toplevel (win_at_pointer); /* get the GtkWidget which owns the toplevel GdkWindow */ gdk_window_get_user_data (toplevel_win, &toplevel); /* toplevel should be an NautilusWindow */ if (toplevel != NULL && NAUTILUS_IS_WINDOW (toplevel)) { return NAUTILUS_NOTEBOOK (NAUTILUS_WINDOW (toplevel)->details->notebook); } return NULL; }
GdkWindow * do_find_current_window (void) { GdkWindow *current_window; GdkDeviceManager *manager; GdkDevice *device; current_window = screenshot_find_active_window (); manager = gdk_display_get_device_manager (gdk_display_get_default ()); device = gdk_device_manager_get_client_pointer (manager); /* If there's no active window, we fall back to returning the * window that the cursor is in. */ if (!current_window) current_window = gdk_device_get_window_at_position (device, NULL, NULL); if (current_window) { if (screenshot_window_is_desktop (current_window)) /* if the current window is the desktop (e.g. nautilus), we * return NULL, as getting the whole screen makes more sense. */ return NULL; /* Once we have a window, we take the toplevel ancestor. */ current_window = gdk_window_get_toplevel (current_window); } return current_window; }
static void tooltip_trigger(void) { GdkDisplay *display = gdk_display_get_default(); #if GTK_CHECK_VERSION(3, 0, 0) GdkDeviceManager *manager = gdk_display_get_device_manager(display); GdkDevice *device = gdk_device_manager_get_client_pointer(manager); GdkWindow *window = gdk_device_get_window_at_position(device, NULL, NULL); #else GdkWindow *window = gdk_display_get_window_at_pointer(display, NULL, NULL); #endif GeanyDocument *doc = document_get_current(); if (doc && window) { GtkWidget *event_widget; gdk_window_get_user_data(window, (void **) &event_widget); /* if you know a better working way, do not hesistate to tell me */ if (event_widget && gtk_widget_is_ancestor(event_widget, GTK_WIDGET(doc->editor->sci))) { gtk_tooltip_trigger_tooltip_query(display); } } }
/** * gtk_tooltip_trigger_tooltip_query: * @display: a #GdkDisplay * * Triggers a new tooltip query on @display, in order to update the current * visible tooltip, or to show/hide the current tooltip. This function is * useful to call when, for example, the state of the widget changed by a * key press. * * Since: 2.12 */ void gtk_tooltip_trigger_tooltip_query (GdkDisplay *display) { gint x, y; GdkWindow *window; GdkEvent event; GdkDevice *device; /* Trigger logic as if the mouse moved */ device = gdk_device_manager_get_client_pointer (gdk_display_get_device_manager (display)); window = gdk_device_get_window_at_position (device, &x, &y); if (!window) return; event.type = GDK_MOTION_NOTIFY; event.motion.window = window; event.motion.x = x; event.motion.y = y; event.motion.is_hint = FALSE; gdk_window_get_root_coords (window, x, y, &x, &y); event.motion.x_root = x; event.motion.y_root = y; _gtk_tooltip_handle_event (&event); }
void DragAndDropHandler::finishDrag(GdkDragContext* context) { #if GTK_CHECK_VERSION(3, 16, 0) // This can happen when attempting to call finish drag from webkitWebViewBaseDragEnd() // for a obsolete DnD operation that got previously cancelled in startDrag(). if (m_dragContext.get() != context) return; if (!m_draggingSelectionData) return; m_dragContext = nullptr; m_draggingSelectionData = nullptr; #else if (!m_draggingSelectionDataMap.remove(context)) return; #endif GdkDevice* device = gdk_drag_context_get_device(context); int x = 0, y = 0; gdk_device_get_window_at_position(device, &x, &y); int xRoot = 0, yRoot = 0; gdk_device_get_position(device, nullptr, &xRoot, &yRoot); m_page.dragEnded(IntPoint(x, y), IntPoint(xRoot, yRoot), gdkDragActionToDragOperation(gdk_drag_context_get_selected_action(context))); }
void DragAndDropHandler::finishDrag(GdkDragContext* context) { if (!m_draggingDataObjects.remove(context)) return; GdkDevice* device = gdk_drag_context_get_device(context); int x = 0, y = 0; gdk_device_get_window_at_position(device, &x, &y); int xRoot = 0, yRoot = 0; gdk_device_get_position(device, nullptr, &xRoot, &yRoot); m_page.dragEnded(IntPoint(x, y), IntPoint(xRoot, yRoot), gdkDragActionToDragOperation(gdk_drag_context_get_selected_action(context))); }
/** * 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; }
/* 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; }
static void get_rgba_at_cursor (GstyleEyedropper *self, GdkScreen *screen, GdkDevice *device, gint x, gint y, GdkRGBA *rgba) { GdkWindow *window; GdkPixbuf *pixbuf; guchar *pixels; g_assert (GSTYLE_IS_EYEDROPPER (self)); g_assert (GDK_IS_SCREEN (screen)); g_assert (GDK_IS_DEVICE (device)); window = gdk_screen_get_root_window (screen); pixbuf = gdk_pixbuf_get_from_window (window, x, y, 1, 1); if (!pixbuf) { window = gdk_device_get_window_at_position (device, &x, &y); if (!window) return; pixbuf = gdk_pixbuf_get_from_window (window, x, y, 1, 1); if (!pixbuf) return; } g_assert (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB); g_assert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8); pixels = gdk_pixbuf_get_pixels (pixbuf); rgba->red = pixels[0] / 255.0; rgba->green = pixels[1] / 255.0; rgba->blue = pixels[2] /255.0; rgba->alpha = 1.0; g_object_unref (pixbuf); }
/* FIXME remove when gtknotebook's func for this becomes public, bug #.... */ static CajaNotebook * find_notebook_at_pointer (gint abs_x, gint abs_y) { #if GTK_CHECK_VERSION(3, 0, 0) GdkDeviceManager *manager; GdkDevice *pointer; #endif GdkWindow *win_at_pointer, *toplevel_win; gpointer toplevel = NULL; gint x, y; /* FIXME multi-head */ #if GTK_CHECK_VERSION(3, 0, 0) manager = gdk_display_get_device_manager (gdk_display_get_default ()); pointer = gdk_device_manager_get_client_pointer (manager); win_at_pointer = gdk_device_get_window_at_position (pointer, &x, &y); #else win_at_pointer = gdk_window_at_pointer (&x, &y); #endif if (win_at_pointer == NULL) { /* We are outside all windows containing a notebook */ return NULL; } toplevel_win = gdk_window_get_toplevel (win_at_pointer); /* get the GtkWidget which owns the toplevel GdkWindow */ gdk_window_get_user_data (toplevel_win, &toplevel); /* toplevel should be an CajaWindow */ if (toplevel != NULL && CAJA_IS_NAVIGATION_WINDOW (toplevel)) { return CAJA_NOTEBOOK (CAJA_NAVIGATION_WINDOW_PANE (CAJA_WINDOW (toplevel)->details->active_pane)->notebook); } return NULL; }
/** * 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; }
static GtkWidget * find_widget_at_pointer (GdkDevice *device) { GtkWidget *widget = NULL; GdkWindow *pointer_window; gint x, y; FindWidgetData data; pointer_window = gdk_device_get_window_at_position (device, NULL, NULL); if (pointer_window) { gpointer widget_ptr; gdk_window_get_user_data (pointer_window, &widget_ptr); widget = widget_ptr; } if (widget) { gdk_window_get_device_position (gtk_widget_get_window (widget), device, &x, &y, NULL); data.x = x; data.y = y; data.found = FALSE; data.first = TRUE; find_widget (widget, &data); if (data.found) return data.res_widget; return widget; } return NULL; }
gboolean gdk_input_other_event (GdkDisplay *display, GdkEvent *event, MSG *msg, GdkWindow *window) { GdkDeviceManagerWin32 *device_manager; GdkDeviceWintab *source_device = NULL; GdkDeviceGrabInfo *last_grab; GdkEventMask masktest; guint key_state; POINT pt; PACKET packet; gint root_x, root_y; gint num_axes; gint x, y; guint translated_buttons, button_diff, button_mask; /* Translation from tablet button state to GDK button state for * buttons 1-3 - swap button 2 and 3. */ static guint button_map[8] = {0, 1, 4, 5, 2, 3, 6, 7}; if (event->any.window != wintab_window) { g_warning ("gdk_input_other_event: not wintab_window?"); return FALSE; } G_GNUC_BEGIN_IGNORE_DEPRECATIONS; device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (display)); G_GNUC_END_IGNORE_DEPRECATIONS; window = gdk_device_get_window_at_position (device_manager->core_pointer, &x, &y); if (window == NULL) window = gdk_get_default_root_window (); g_object_ref (window); GDK_NOTE (EVENTS_OR_INPUT, g_print ("gdk_input_other_event: window=%p %+d%+d\n", GDK_WINDOW_HWND (window), x, y)); if (msg->message == WT_PACKET || msg->message == WT_CSRCHANGE) { if (!(*p_WTPacket) ((HCTX) msg->lParam, msg->wParam, &packet)) return FALSE; } switch (msg->message) { case WT_PACKET: /* Don't produce any button or motion events while a window is being * moved or resized, see bug #151090. */ if (_modal_operation_in_progress) { GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n")); return FALSE; } if ((source_device = gdk_device_manager_find_wintab_device (device_manager, (HCTX) msg->lParam, packet.pkCursor)) == NULL) return FALSE; if (gdk_device_get_mode (GDK_DEVICE (source_device)) == GDK_MODE_DISABLED) return FALSE; last_grab = _gdk_display_get_last_device_grab (display, GDK_DEVICE (source_device)); if (last_grab && last_grab->window) { g_object_unref (window); window = g_object_ref (last_grab->window); } if (window == gdk_get_default_root_window ()) { GDK_NOTE (EVENTS_OR_INPUT, g_print ("... is root\n")); return FALSE; } num_axes = 0; if (source_device->pktdata & PK_X) source_device->last_axis_data[num_axes++] = packet.pkX; if (source_device->pktdata & PK_Y) source_device->last_axis_data[num_axes++] = packet.pkY; if (source_device->pktdata & PK_NORMAL_PRESSURE) source_device->last_axis_data[num_axes++] = packet.pkNormalPressure; if (source_device->pktdata & PK_ORIENTATION) { decode_tilt (source_device->last_axis_data + num_axes, source_device->orientation_axes, &packet); num_axes += 2; } translated_buttons = button_map[packet.pkButtons & 0x07] | (packet.pkButtons & ~0x07); if (translated_buttons != source_device->button_state) { /* At least one button has changed state so produce a button event * If more than one button has changed state (unlikely), * just care about the first and act on the next the next time * we get a packet */ button_diff = translated_buttons ^ source_device->button_state; /* Gdk buttons are numbered 1.. */ event->button.button = 1; for (button_mask = 1; button_mask != 0x80000000; button_mask <<= 1, event->button.button++) { if (button_diff & button_mask) { /* Found a button that has changed state */ break; } } if (!(translated_buttons & button_mask)) { event->any.type = GDK_BUTTON_RELEASE; masktest = GDK_BUTTON_RELEASE_MASK; } else { event->any.type = GDK_BUTTON_PRESS; masktest = GDK_BUTTON_PRESS_MASK; } source_device->button_state ^= button_mask; } else { event->any.type = GDK_MOTION_NOTIFY; masktest = GDK_POINTER_MOTION_MASK; if (source_device->button_state & (1 << 0)) masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK; if (source_device->button_state & (1 << 1)) masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON2_MOTION_MASK; if (source_device->button_state & (1 << 2)) masktest |= GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK; } /* Now we can check if the window wants the event, and * propagate if necessary. */ while ((gdk_window_get_device_events (window, GDK_DEVICE (source_device)) & masktest) == 0 && (gdk_device_get_device_type (GDK_DEVICE (source_device)) == GDK_DEVICE_TYPE_SLAVE && (gdk_window_get_events (window) & masktest) == 0)) { GDK_NOTE (EVENTS_OR_INPUT, g_print ("... not selected\n")); if (window->parent == gdk_get_default_root_window () || window->parent == NULL) return FALSE; pt.x = x; pt.y = y; ClientToScreen (GDK_WINDOW_HWND (window), &pt); g_object_unref (window); window = window->parent; g_object_ref (window); ScreenToClient (GDK_WINDOW_HWND (window), &pt); x = pt.x; y = pt.y; GDK_NOTE (EVENTS_OR_INPUT, g_print ("... propagating to %p %+d%+d\n", GDK_WINDOW_HWND (window), x, y)); } event->any.window = window; key_state = get_modifier_key_state (); if (event->any.type == GDK_BUTTON_PRESS || event->any.type == GDK_BUTTON_RELEASE) { event->button.time = _gdk_win32_get_next_tick (msg->time); if (source_device->sends_core) gdk_event_set_device (event, device_manager->core_pointer); gdk_event_set_source_device (event, GDK_DEVICE (source_device)); gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer)); event->button.axes = g_new (gdouble, num_axes); gdk_window_get_origin (window, &root_x, &root_y); _gdk_device_wintab_translate_axes (source_device, window, event->button.axes, &event->button.x, &event->button.y); event->button.x_root = event->button.x + root_x; event->button.y_root = event->button.y + root_y; event->button.state = key_state | ((source_device->button_state << 8) & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)); GDK_NOTE (EVENTS_OR_INPUT, g_print ("WINTAB button %s:%d %g,%g\n", (event->button.type == GDK_BUTTON_PRESS ? "press" : "release"), event->button.button, event->button.x, event->button.y)); } else { event->motion.time = _gdk_win32_get_next_tick (msg->time); event->motion.is_hint = FALSE; gdk_event_set_device (event, device_manager->core_pointer); gdk_event_set_source_device (event, GDK_DEVICE (source_device)); gdk_event_set_seat (event, gdk_device_get_seat (device_manager->core_pointer)); event->motion.axes = g_new (gdouble, num_axes); gdk_window_get_origin (window, &root_x, &root_y); _gdk_device_wintab_translate_axes (source_device, window, event->motion.axes, &event->motion.x, &event->motion.y); event->motion.x_root = event->motion.x + root_x; event->motion.y_root = event->motion.y + root_y; event->motion.state = key_state | ((source_device->button_state << 8) & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)); GDK_NOTE (EVENTS_OR_INPUT, g_print ("WINTAB motion: %g,%g\n", event->motion.x, event->motion.y)); } return TRUE; case WT_CSRCHANGE: if ((source_device = gdk_device_manager_find_wintab_device (device_manager, (HCTX) msg->lParam, packet.pkCursor)) == NULL) return FALSE; if (gdk_device_get_mode (GDK_DEVICE (source_device)) == GDK_MODE_DISABLED) return FALSE; if (source_device->sends_core) { _gdk_device_virtual_set_active (device_manager->core_pointer, GDK_DEVICE (source_device)); _gdk_input_ignore_core = TRUE; } return FALSE; case WT_PROXIMITY: if (LOWORD (msg->lParam) == 0) { _gdk_input_ignore_core = FALSE; _gdk_device_virtual_set_active (device_manager->core_pointer, device_manager->system_pointer); } return FALSE; } return FALSE; }
static void gimp_pick_button_pick (GimpPickButton *button, GdkEvent *event) { GdkScreen *screen = gdk_event_get_screen (event); GimpColorProfile *monitor_profile; GdkMonitor *monitor; GimpRGB rgb; gint x_root; gint y_root; gdouble x_win; gdouble y_win; gdk_window_get_origin (gdk_event_get_window (event), &x_root, &y_root); gdk_event_get_coords (event, &x_win, &y_win); x_root += x_win; y_root += y_win; #ifdef G_OS_WIN32 { HDC hdc; RECT rect; COLORREF win32_color; /* For MS Windows, use native GDI functions to get the pixel, as * cairo does not handle the case where you have multiple monitors * with a monitor on the left or above the primary monitor. That * scenario create a cairo primary surface with negative extent, * which is not handled properly (bug 740634). */ hdc = GetDC (HWND_DESKTOP); GetClipBox (hdc, &rect); win32_color = GetPixel (hdc, x_root + rect.left, y_root + rect.top); ReleaseDC (HWND_DESKTOP, hdc); gimp_rgba_set_uchar (&rgb, GetRValue (win32_color), GetGValue (win32_color), GetBValue (win32_color), 255); } #else { GdkWindow *window; gint x_window; gint y_window; cairo_surface_t *image; cairo_t *cr; guchar *data; guchar color[3]; /* we try to pick from the local window under the cursor, and fall * back to picking from the root window if this fails (i.e., if * the cursor is not under a local window). on wayland, picking * from the root window is not supported, so this at least allows * us to pick from local windows. see bug #780375. */ window = gdk_device_get_window_at_position (gdk_event_get_device (event), &x_window, &y_window); if (! window) { window = gdk_screen_get_root_window (screen); x_window = x_root; y_window = y_root; } image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1); cr = cairo_create (image); gdk_cairo_set_source_window (cr, window, -x_window, -y_window); cairo_paint (cr); cairo_destroy (cr); data = cairo_image_surface_get_data (image); GIMP_CAIRO_RGB24_GET_PIXEL (data, color[0], color[1], color[2]); cairo_surface_destroy (image); gimp_rgba_set_uchar (&rgb, color[0], color[1], color[2], 255); } #endif monitor = gdk_display_get_monitor_at_point (gdk_screen_get_display (screen), x_root, y_root); monitor_profile = gimp_monitor_get_color_profile (monitor); if (monitor_profile) { GimpColorProfile *srgb_profile; GimpColorTransform *transform; const Babl *format; GimpColorTransformFlags flags = 0; format = babl_format ("R'G'B'A double"); flags |= GIMP_COLOR_TRANSFORM_FLAGS_NOOPTIMIZE; flags |= GIMP_COLOR_TRANSFORM_FLAGS_BLACK_POINT_COMPENSATION; srgb_profile = gimp_color_profile_new_rgb_srgb (); transform = gimp_color_transform_new (monitor_profile, format, srgb_profile, format, GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL, flags); g_object_unref (srgb_profile); if (transform) { gimp_color_transform_process_pixels (transform, format, &rgb, format, &rgb, 1); gimp_rgb_clamp (&rgb); g_object_unref (transform); } } g_signal_emit_by_name (button, "color-picked", &rgb); }