diff options
author | Hans Breuer <hans@breuer.org> | 2001-08-19 18:34:59 +0000 |
---|---|---|
committer | Hans Breuer <hans@src.gnome.org> | 2001-08-19 18:34:59 +0000 |
commit | f34e996b5f41a903e67f2143014e7f7b4e5a92e9 (patch) | |
tree | b9f6d4a5ec66190117d12b8b87ac7e11e0eae73e /gdk | |
parent | dedfce8ab887e37d3d5d56fbb373d4724b4cbbab (diff) | |
download | gtk+-f34e996b5f41a903e67f2143014e7f7b4e5a92e9.tar.gz |
updated externals
2001-08-18 Hans Breuer <hans@breuer.org>
* gdk/gdk.def : updated externals
* gdk/win32/gdkselection-win32.c : returning TRUE with gdk_selection_set
is required to get (at least) visible in entry fields. Some selections
are really handled now - even on win32 - but copying via middle
mouse button into a different app needs to wait ...
* gdk/win32/gdkdnd-win32.c : implemented inter-app drag&drop
mostly by stealling code from gdkdnd-fb.c. Thanks to who ever wrote it!
* gdk/win32/gdkevents-win32.c : some tweaking to get better expose
handling. I'm not sure if it is better now, but at least not worse
* gdk/win32/gdkgeometry-win32.c : replaced every call to MoveWindow
with SetWindowPos () which allows more fine-tuning backing-store wise
* gdk/win32/gdkwindow-win32.c : allow unraised gdk_window_show ().
Also changed move/resize to be more like the X version.
* gtk/gtk.def : updated externals
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/gdk.def | 25 | ||||
-rw-r--r-- | gdk/win32/gdkdnd-win32.c | 424 | ||||
-rw-r--r-- | gdk/win32/gdkevents-win32.c | 76 | ||||
-rw-r--r-- | gdk/win32/gdkgeometry-win32.c | 115 | ||||
-rw-r--r-- | gdk/win32/gdkselection-win32.c | 47 | ||||
-rw-r--r-- | gdk/win32/gdkwindow-win32.c | 88 |
6 files changed, 644 insertions, 131 deletions
diff --git a/gdk/gdk.def b/gdk/gdk.def index 2e72b8a214..f687d6b9f0 100644 --- a/gdk/gdk.def +++ b/gdk/gdk.def @@ -1,8 +1,10 @@ EXPORTS gdk_atom_intern gdk_atom_name + gdk_axis_use_get_type gdk_beep gdk_bitmap_create_from_data + gdk_byte_order_get_type gdk_cap_style_get_type gdk_char_height gdk_char_measure @@ -34,6 +36,7 @@ EXPORTS gdk_colors_free gdk_colors_store gdk_core_pointer + gdk_crossing_mode_get_type gdk_cursor_new gdk_cursor_new_from_pixmap gdk_cursor_ref @@ -124,11 +127,14 @@ EXPORTS gdk_event_queue_remove_link gdk_event_send_client_message gdk_event_send_clientmessage_toall + gdk_event_type_get_type gdk_event_unqueue gdk_events_pending gdk_exit gdk_extension_mode_get_type gdk_fill_get_type + gdk_fill_rule_get_type + gdk_filter_return_get_type gdk_flush gdk_font_equal gdk_font_from_description @@ -138,6 +144,7 @@ EXPORTS gdk_font_id gdk_font_load gdk_font_ref + gdk_font_type_get_type gdk_font_unref gdk_fontset_load gdk_free_compound_text @@ -173,6 +180,7 @@ EXPORTS gdk_get_display gdk_get_show_events gdk_get_use_xshm + gdk_grab_status_get_type gdk_gravity_get_type gdk_image_get gdk_image_get_pixel @@ -190,9 +198,11 @@ EXPORTS gdk_input_condition_get_type gdk_input_exit gdk_input_init + gdk_input_mode_get_type gdk_input_motion_events gdk_input_remove gdk_input_set_extension_events + gdk_input_source_get_type gdk_join_style_get_type gdk_key_repeat_disable gdk_key_repeat_restore @@ -217,7 +227,9 @@ EXPORTS gdk_list_visuals gdk_mbstowcs gdk_modifier_type_get_type + gdk_notify_type_get_type gdk_null_window_warnings + gdk_overlap_type_get_type gdk_pango_attr_embossed_new gdk_pango_attr_stipple_new gdk_pango_context_get @@ -245,6 +257,7 @@ EXPORTS gdk_property_change gdk_property_delete gdk_property_get + gdk_property_state_get_type gdk_query_depths gdk_query_visual_types gdk_rectangle_get_type @@ -284,7 +297,9 @@ EXPORTS gdk_screen_height_mm gdk_screen_width gdk_screen_width_mm + gdk_scroll_direction_get_type gdk_selection_convert + gdk_selection_get_type gdk_selection_owner_get gdk_selection_owner_set gdk_selection_property @@ -295,7 +310,9 @@ EXPORTS gdk_set_show_events gdk_set_sm_client_id gdk_set_use_xshm + gdk_setting_action_get_type gdk_setting_get + gdk_status_get_type gdk_string_extents gdk_string_height gdk_string_measure @@ -303,6 +320,7 @@ EXPORTS gdk_string_width gdk_subwindow_mode_get_type gdk_synthesize_window_state + gdk_target_get_type gdk_text_extents gdk_text_extents_wc gdk_text_height @@ -317,6 +335,7 @@ EXPORTS gdk_unicode_to_keyval gdk_utf8_to_compound_text gdk_utf8_to_string_target + gdk_visibility_state_get_type gdk_visual_get_best gdk_visual_get_best_depth gdk_visual_get_best_type @@ -332,10 +351,12 @@ EXPORTS gdk_win32_hdc_release gdk_window_add_filter gdk_window_at_pointer + gdk_window_attributes_type_get_type gdk_window_begin_move_drag gdk_window_begin_paint_rect gdk_window_begin_paint_region gdk_window_begin_resize_drag + gdk_window_class_get_type gdk_window_clear gdk_window_clear_area gdk_window_clear_area_e @@ -343,6 +364,7 @@ EXPORTS gdk_window_deiconify gdk_window_destroy gdk_window_destroy_notify + gdk_window_edge_get_type gdk_window_end_paint gdk_window_focus gdk_window_foreign_new @@ -362,6 +384,7 @@ EXPORTS gdk_window_get_user_data gdk_window_get_window_type gdk_window_hide + gdk_window_hints_get_type gdk_window_iconify gdk_window_invalidate_rect gdk_window_invalidate_region @@ -407,8 +430,10 @@ EXPORTS gdk_window_shape_combine_mask gdk_window_shape_combine_region gdk_window_show + gdk_window_state_get_type gdk_window_stick gdk_window_thaw_updates + gdk_window_type_get_type gdk_window_type_hint_get_type gdk_window_unmaximize gdk_window_unstick diff --git a/gdk/win32/gdkdnd-win32.c b/gdk/win32/gdkdnd-win32.c index fa2c9fabf8..a5ed72b802 100644 --- a/gdk/win32/gdkdnd-win32.c +++ b/gdk/win32/gdkdnd-win32.c @@ -89,15 +89,16 @@ static int nformats; * this is used on both source and destination sides. */ struct _GdkDragContextPrivateWin32 { - gint ref_count; + GdkAtom local_selection; + gint ref_count; guint16 last_x; /* Coordinates from last event */ guint16 last_y; - HWND dest_xid; - guint drag_status; /* Current status of drag */ + HWND dest_xid; + guint drag_status; /* Current status of drag */ }; -#define PRIVATE_DATA(context) ((GdkDragContextPrivateWin32 *) GDK_DRAG_CONTEXT (context)->windowing_data) +#define GDK_DRAG_CONTEXT_PRIVATE_DATA(context) ((GdkDragContextPrivateWin32 *) GDK_DRAG_CONTEXT (context)->windowing_data) GdkDragContext *current_dest_drag = NULL; @@ -161,7 +162,7 @@ static void gdk_drag_context_finalize (GObject *object) { GdkDragContext *context = GDK_DRAG_CONTEXT (object); - GdkDragContextPrivateWin32 *private = PRIVATE_DATA (context); + GdkDragContextPrivateWin32 *private = GDK_DRAG_CONTEXT_PRIVATE_DATA (context); g_list_free (context->targets); @@ -204,34 +205,32 @@ gdk_drag_context_unref (GdkDragContext *context) g_object_unref (G_OBJECT (context)); } -#if 0 - static GdkDragContext * -gdk_drag_context_find (gboolean is_source, - HWND source_xid, - HWND dest_xid) +gdk_drag_context_find (gboolean is_source, + GdkWindow *source, + GdkWindow *dest) { GList *tmp_list = contexts; + GdkDragContext *context; + GdkDragContextPrivateWin32 *private; while (tmp_list) { context = (GdkDragContext *)tmp_list->data; + private = GDK_DRAG_CONTEXT_PRIVATE_DATA (context); if ((!context->is_source == !is_source) && - ((source_xid == None) || (context->source_window && - (GDK_WINDOW_XWINDOW (context->source_window) == source_xid))) && - ((dest_xid == None) || (context->dest_window && - (GDK_WINDOW_XWINDOW (context->dest_window) == dest_xid)))) - return context; + ((source == NULL) || (context->source_window && (context->source_window == source))) && + ((dest == NULL) || (context->dest_window && (context->dest_window == dest)))) + return context; tmp_list = tmp_list->next; } - + return NULL; } -#endif typedef struct { #ifdef OLE2_DND @@ -266,7 +265,7 @@ static ULONG STDMETHODCALLTYPE idroptarget_addref (LPDROPTARGET This) { target_drag_context *ctx = (target_drag_context *) This; - GdkDragContextPrivateWin32 *private = PRIVATE_DATA (ctx->context); + GdkDragContextPrivateWin32 *private = GDK_DRAG_CONTEXT_PRIVATE_DATA (ctx->context); int ref_count = ++private->ref_count; gdk_drag_context_ref (ctx->context); @@ -311,7 +310,7 @@ static ULONG STDMETHODCALLTYPE idroptarget_release (LPDROPTARGET This) { target_drag_context *ctx = (target_drag_context *) This; - GdkDragContextPrivateWin32 *private = PRIVATE_DATA (ctx->context); + GdkDragContextPrivateWin32 *private = GDK_DRAG_CONTEXT_PRIVATE_DATA (ctx->context); int ref_count = --private->ref_count; gdk_drag_context_unref (ctx->context); @@ -370,7 +369,7 @@ static ULONG STDMETHODCALLTYPE idropsource_addref (LPDROPSOURCE This) { source_drag_context *ctx = (source_drag_context *) This; - GdkDragContextPrivateWin32 *private = PRIVATE_DATA (ctx->context); + GdkDragContextPrivateWin32 *private = GDK_DRAG_CONTEXT_PRIVATE_DATA (ctx->context); gdk_drag_context_ref (ctx->context); GDK_NOTE (DND, g_print ("idropsource_addref %#x %d\n", @@ -414,7 +413,7 @@ static ULONG STDMETHODCALLTYPE idropsource_release (LPDROPSOURCE This) { source_drag_context *ctx = (source_drag_context *) This; - GdkDragContextPrivateWin32 *private = PRIVATE_DATA (ctx->context); + GdkDragContextPrivateWin32 *private = GDK_DRAG_CONTEXT_PRIVATE_DATA (ctx->context); int ref_count = --private->ref_count; gdk_drag_context_unref (ctx->context); @@ -962,10 +961,11 @@ gdk_dropfiles_filter (GdkXEvent *xev, GDK_NOTE (DND, g_print ("WM_DROPFILES: %#x\n", (guint) msg->hwnd)); context = gdk_drag_context_new (); - private = PRIVATE_DATA (context); + private = GDK_DRAG_CONTEXT_PRIVATE_DATA (context); context->protocol = GDK_DRAG_PROTO_WIN32_DROPFILES; context->is_source = FALSE; context->source_window = gdk_parent_root; + gdk_drawable_ref (context->source_window); context->dest_window = event->any.window; gdk_drawable_ref (context->dest_window); /* WM_DROPFILES drops are always file names */ @@ -1060,12 +1060,163 @@ gdk_win32_dnd_exit (void) /* Source side */ static void +local_send_leave (GdkDragContext *context, + guint32 time) +{ + GdkEvent tmp_event; + + if ((current_dest_drag != NULL) && + (current_dest_drag->protocol == GDK_DRAG_PROTO_LOCAL) && + (current_dest_drag->source_window == context->source_window)) + { + tmp_event.dnd.type = GDK_DRAG_LEAVE; + tmp_event.dnd.window = context->dest_window; + /* Pass ownership of context to the event */ + tmp_event.dnd.context = current_dest_drag; + tmp_event.dnd.send_event = FALSE; + tmp_event.dnd.time = GDK_CURRENT_TIME; /* FIXME? */ + + current_dest_drag = NULL; + + gdk_event_put (&tmp_event); + } + +} + +static void +local_send_enter (GdkDragContext *context, + guint32 time) +{ + GdkEvent tmp_event; + GdkDragContextPrivateWin32 *private; + GdkDragContext *new_context; + + private = GDK_DRAG_CONTEXT_PRIVATE_DATA (context); + + if (!private->local_selection) + private->local_selection = gdk_atom_intern ("LocalDndSelection", FALSE); + + if (current_dest_drag != NULL) + { + gdk_drag_context_unref (current_dest_drag); + current_dest_drag = NULL; + } + + new_context = gdk_drag_context_new (); + new_context->protocol = GDK_DRAG_PROTO_LOCAL; + new_context->is_source = FALSE; + + new_context->source_window = context->source_window; + gdk_window_ref (new_context->source_window); + new_context->dest_window = context->dest_window; + gdk_window_ref (new_context->dest_window); + + + new_context->targets = g_list_copy (context->targets); + + gdk_window_set_events (new_context->source_window, + gdk_window_get_events (new_context->source_window) | + GDK_PROPERTY_CHANGE_MASK); + new_context->actions = context->actions; + + tmp_event.dnd.type = GDK_DRAG_ENTER; + tmp_event.dnd.window = context->dest_window; + tmp_event.dnd.send_event = FALSE; + tmp_event.dnd.context = new_context; + gdk_drag_context_ref (new_context); + + tmp_event.dnd.time = GDK_CURRENT_TIME; /* FIXME? */ + + current_dest_drag = new_context; + + (GDK_DRAG_CONTEXT_PRIVATE_DATA (new_context))->local_selection = + private->local_selection; + + gdk_event_put (&tmp_event); +} + +static void +local_send_motion (GdkDragContext *context, + gint x_root, + gint y_root, + GdkDragAction action, + guint32 time) +{ + GdkEvent tmp_event; + + if ((current_dest_drag != NULL) && + (current_dest_drag->protocol == GDK_DRAG_PROTO_LOCAL) && + (current_dest_drag->source_window == context->source_window)) + { + tmp_event.dnd.type = GDK_DRAG_MOTION; + tmp_event.dnd.window = current_dest_drag->dest_window; + tmp_event.dnd.send_event = FALSE; + tmp_event.dnd.context = current_dest_drag; + gdk_drag_context_ref (current_dest_drag); + + tmp_event.dnd.time = time; + + current_dest_drag->suggested_action = action; + current_dest_drag->actions = current_dest_drag->suggested_action; + + tmp_event.dnd.x_root = x_root; + tmp_event.dnd.y_root = y_root; + + (GDK_DRAG_CONTEXT_PRIVATE_DATA (current_dest_drag))->last_x = x_root; + (GDK_DRAG_CONTEXT_PRIVATE_DATA (current_dest_drag))->last_y = y_root; + + GDK_DRAG_CONTEXT_PRIVATE_DATA (context)->drag_status = GDK_DRAG_STATUS_MOTION_WAIT; + + gdk_event_put (&tmp_event); + } +} + +static void +local_send_drop (GdkDragContext *context, guint32 time) +{ + GdkEvent tmp_event; + + if ((current_dest_drag != NULL) && + (current_dest_drag->protocol == GDK_DRAG_PROTO_LOCAL) && + (current_dest_drag->source_window == context->source_window)) + { + GdkDragContextPrivateWin32 *private; + private = GDK_DRAG_CONTEXT_PRIVATE_DATA (current_dest_drag); + + tmp_event.dnd.type = GDK_DROP_START; + tmp_event.dnd.window = current_dest_drag->dest_window; + tmp_event.dnd.send_event = FALSE; + + tmp_event.dnd.context = current_dest_drag; + gdk_drag_context_ref (current_dest_drag); + + tmp_event.dnd.time = GDK_CURRENT_TIME; + + tmp_event.dnd.x_root = private->last_x; + tmp_event.dnd.y_root = private->last_y; + + gdk_event_put (&tmp_event); + } + +} + +static void gdk_drag_do_leave (GdkDragContext *context, guint32 time) { if (context->dest_window) { GDK_NOTE (DND, g_print ("gdk_drag_do_leave\n")); + + switch (context->protocol) + { + case GDK_DRAG_PROTO_LOCAL: + local_send_leave (context, time); + break; + default: + break; + } + gdk_drawable_unref (context->dest_window); context->dest_window = NULL; } @@ -1075,8 +1226,31 @@ GdkDragContext * gdk_drag_begin (GdkWindow *window, GList *targets) { +#ifndef OLE2_DND + GList *tmp_list; + GdkDragContext *new_context; + + g_return_val_if_fail (window != NULL, NULL); + + new_context = gdk_drag_context_new (); + new_context->is_source = TRUE; + new_context->source_window = window; + gdk_window_ref (window); + + tmp_list = g_list_last (targets); + new_context->targets = NULL; + while (tmp_list) + { + new_context->targets = g_list_prepend (new_context->targets, + tmp_list->data); + tmp_list = tmp_list->prev; + } + + new_context->actions = 0; + + return new_context; +#else source_drag_context *ctx; -#ifdef OLE2_DND GList *tmp_list; data_object *dobj; HRESULT hResult; @@ -1084,7 +1258,6 @@ gdk_drag_begin (GdkWindow *window, HGLOBAL global; FORMATETC format; STGMEDIUM medium; -#endif g_return_val_if_fail (window != NULL, NULL); @@ -1095,7 +1268,6 @@ gdk_drag_begin (GdkWindow *window, ctx->context->source_window = window; gdk_drawable_ref (window); -#ifdef OLE2_DND tmp_list = g_list_last (targets); ctx->context->targets = NULL; while (tmp_list) @@ -1129,15 +1301,28 @@ gdk_drag_begin (GdkWindow *window, dobj->ido.lpVtbl->Release (&dobj->ido); ctx->ids.lpVtbl->Release (&ctx->ids); -#endif + return ctx->context; +#endif } guint32 gdk_drag_get_protocol (guint32 xid, GdkDragProtocol *protocol) { - /* This isn't used */ + GdkWindow *window; + + GDK_NOTE (DND, g_print ("gdk_drag_get_protocol\n")); + + window = gdk_window_lookup (xid); + + + if (GPOINTER_TO_INT (gdk_drawable_get_data (window, "gdk-dnd-registered"))) + { + *protocol = GDK_DRAG_PROTO_LOCAL; + return xid; + } + return 0; } @@ -1152,10 +1337,6 @@ gdk_drag_find_window (GdkDragContext *context, HWND recipient; POINT pt; - GDK_NOTE (DND, g_print ("gdk_drag_find_window: %#x +%d+%d\n", - (drag_window ? (guint) GDK_WINDOW_HWND (drag_window) : 0), - x_root, y_root)); - pt.x = x_root; pt.y = y_root; recipient = WindowFromPoint (pt); @@ -1166,8 +1347,17 @@ gdk_drag_find_window (GdkDragContext *context, *dest_window = gdk_win32_handle_table_lookup (GPOINTER_TO_UINT(recipient)); if (*dest_window) gdk_drawable_ref (*dest_window); - *protocol = GDK_DRAG_PROTO_WIN32_DROPFILES; + + if (context->source_window) + *protocol = GDK_DRAG_PROTO_LOCAL; + else + *protocol = GDK_DRAG_PROTO_WIN32_DROPFILES; } + + GDK_NOTE (DND, g_print ("gdk_drag_find_window: %#x +%d+%d Protocol: %d\n", + (drag_window ? (guint) GDK_WINDOW_HWND (drag_window) : 0), + x_root, y_root, *protocol)); + } gboolean @@ -1180,8 +1370,94 @@ gdk_drag_motion (GdkDragContext *context, GdkDragAction possible_actions, guint32 time) { + GdkDragContextPrivateWin32 *private; + + g_return_val_if_fail (context != NULL, FALSE); + GDK_NOTE (DND, g_print ("gdk_drag_motion\n")); + private = GDK_DRAG_CONTEXT_PRIVATE_DATA (context); + + if (context->dest_window != dest_window) + { + GdkEvent temp_event; + + /* Send a leave to the last destination */ + gdk_drag_do_leave (context, time); + private->drag_status = GDK_DRAG_STATUS_DRAG; + + /* Check if new destination accepts drags, and which protocol */ + if (dest_window) + { + context->dest_window = dest_window; + gdk_window_ref (context->dest_window); + context->protocol = protocol; + + switch (protocol) + { + case GDK_DRAG_PROTO_LOCAL: + local_send_enter (context, time); + break; + + + default: + break; + } + context->suggested_action = suggested_action; + } + else + { + context->dest_window = NULL; + context->action = 0; + } + + /* Push a status event, to let the client know that + * the drag changed + */ + + temp_event.dnd.type = GDK_DRAG_STATUS; + temp_event.dnd.window = context->source_window; + /* We use this to signal a synthetic status. Perhaps + * we should use an extra field... + */ + temp_event.dnd.send_event = TRUE; + + temp_event.dnd.context = context; + temp_event.dnd.time = time; + + gdk_event_put (&temp_event); + } + else + { + context->suggested_action = suggested_action; + } + + /* Send a drag-motion event */ + + private->last_x = x_root; + private->last_y = y_root; + + if (context->dest_window) + { + if (private->drag_status == GDK_DRAG_STATUS_DRAG) + { + switch (context->protocol) + { + case GDK_DRAG_PROTO_LOCAL: + local_send_motion (context, x_root, y_root, suggested_action, time); + break; + + case GDK_DRAG_PROTO_NONE: + g_warning ("GDK_DRAG_PROTO_NONE is not valid in gdk_drag_motion()"); + break; + default: + break; + } + } + else + return TRUE; + } + return FALSE; } @@ -1192,6 +1468,22 @@ gdk_drag_drop (GdkDragContext *context, g_return_if_fail (context != NULL); GDK_NOTE (DND, g_print ("gdk_drag_drop\n")); + + if (context->dest_window) + { + switch (context->protocol) + { + case GDK_DRAG_PROTO_LOCAL: + local_send_drop (context, time); + break; + + case GDK_DRAG_PROTO_NONE: + g_warning ("GDK_DRAG_PROTO_NONE is not valid in gdk_drag_drop()"); + break; + default: + break; + } + } } void @@ -1212,7 +1504,40 @@ gdk_drag_status (GdkDragContext *context, GdkDragAction action, guint32 time) { - GDK_NOTE (DND, g_print ("gdk_drag_status\n")); + GdkDragContextPrivateWin32 *private; + GdkDragContext *src_context; + GdkEvent tmp_event; + + g_return_if_fail (context != NULL); + + private = GDK_DRAG_CONTEXT_PRIVATE_DATA (context); + + src_context = gdk_drag_context_find (TRUE, + context->source_window, + context->dest_window); + + if (src_context) + { + GdkDragContextPrivateWin32 *private = GDK_DRAG_CONTEXT_PRIVATE_DATA (src_context); + + if (private->drag_status == GDK_DRAG_STATUS_MOTION_WAIT) + private->drag_status = GDK_DRAG_STATUS_DRAG; + + tmp_event.dnd.type = GDK_DRAG_STATUS; + tmp_event.dnd.window = context->source_window; + tmp_event.dnd.send_event = FALSE; + tmp_event.dnd.context = src_context; + gdk_drag_context_ref (src_context); + + tmp_event.dnd.time = GDK_CURRENT_TIME; /* FIXME? */ + + if (action == GDK_ACTION_DEFAULT) + action = 0; + + src_context->action = action; + + gdk_event_put (&tmp_event); + } } void @@ -1220,6 +1545,8 @@ gdk_drop_reply (GdkDragContext *context, gboolean ok, guint32 time) { + g_return_if_fail (context != NULL); + GDK_NOTE (DND, g_print ("gdk_drop_reply\n")); } @@ -1228,7 +1555,29 @@ gdk_drop_finish (GdkDragContext *context, gboolean success, guint32 time) { + GdkDragContextPrivateWin32 *private; + GdkDragContext *src_context; + GdkEvent tmp_event; + + g_return_if_fail (context != NULL); + GDK_NOTE (DND, g_print ("gdk_drop_finish\n")); + + private = GDK_DRAG_CONTEXT_PRIVATE_DATA (context); + + src_context = gdk_drag_context_find (TRUE, + context->source_window, + context->dest_window); + if (src_context) + { + tmp_event.dnd.type = GDK_DROP_FINISHED; + tmp_event.dnd.window = src_context->source_window; + tmp_event.dnd.send_event = FALSE; + tmp_event.dnd.context = src_context; + gdk_drag_context_ref (src_context); + + gdk_event_put (&tmp_event); + } } #ifdef OLE2_DND @@ -1265,6 +1614,11 @@ gdk_window_register_dnd (GdkWindow *window) g_return_if_fail (window != NULL); + if (GPOINTER_TO_INT (gdk_drawable_get_data (window, "gdk-dnd-registered"))) + return; + else + gdk_drawable_set_data (window, "gdk-dnd-registered", GINT_TO_POINTER(TRUE), NULL); + GDK_NOTE (DND, g_print ("gdk_window_register_dnd: %#x\n", (guint) GDK_WINDOW_HWND (window))); @@ -1315,7 +1669,9 @@ gdk_window_register_dnd (GdkWindow *window) GdkAtom gdk_drag_get_selection (GdkDragContext *context) { - if (context->protocol == GDK_DRAG_PROTO_WIN32_DROPFILES) + if (context->protocol == GDK_DRAG_PROTO_LOCAL) + return (GDK_DRAG_CONTEXT_PRIVATE_DATA (context))->local_selection; + else if (context->protocol == GDK_DRAG_PROTO_WIN32_DROPFILES) return gdk_win32_dropfiles_atom; else if (context->protocol == GDK_DRAG_PROTO_OLE2) return gdk_ole2_dnd_atom; diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index d5199c906d..6b95b0a1fb 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -1680,6 +1680,7 @@ gdk_event_translate (GdkEvent *event, event->selection.type = GDK_SELECTION_CLEAR; event->selection.window = window; event->selection.selection = msg->wParam; + event->selection.target = msg->lParam; event->selection.time = msg->time; return_val = !GDK_WINDOW_DESTROYED (window); @@ -2531,6 +2532,9 @@ gdk_event_translate (GdkEvent *event, if (GDK_WINDOW_DESTROYED (window)) break; + *ret_val_flagp = TRUE; /* always claim as handled */ + *ret_valp = 1; + if (GDK_WINDOW_OBJECT (window)->input_only) break; @@ -2560,8 +2564,6 @@ gdk_event_translate (GdkEvent *event, colormap_private->xcolormap->palette, k); #endif } - *ret_val_flagp = TRUE; - *ret_valp = 1; if (GDK_WINDOW_OBJECT (window)->bg_pixmap == GDK_PARENT_RELATIVE_BG) { @@ -2577,6 +2579,14 @@ gdk_event_translate (GdkEvent *event, } } + if (GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->position_info.no_bg) + { + /* improves scolling effect, e.g. main buttons of testgtk */ + *ret_val_flagp = TRUE; + *ret_valp = 1; + break; + } + if (GDK_WINDOW_OBJECT (window)->bg_pixmap == NULL) { bg = gdk_colormap_color (GDK_DRAWABLE_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->colormap, @@ -2678,18 +2688,6 @@ gdk_event_translate (GdkEvent *event, break; } - /* HB: don't generate GDK_EXPOSE events for InputOnly - * windows -> backing store now works! - */ - if (GDK_WINDOW_OBJECT (window)->input_only) - break; - - if (!(window_impl->event_mask & GDK_EXPOSURE_MASK)) - break; - - if (GDK_WINDOW_OBJECT (window)->bg_pixmap == GDK_NO_BG) - break; - hdc = BeginPaint (msg->hwnd, &paintstruct); GDK_NOTE (EVENTS, @@ -2703,6 +2701,18 @@ gdk_event_translate (GdkEvent *event, EndPaint (msg->hwnd, &paintstruct); + /* HB: don't generate GDK_EXPOSE events for InputOnly + * windows -> backing store now works! + */ + if (GDK_WINDOW_OBJECT (window)->input_only) + break; + + if (!(window_impl->event_mask & GDK_EXPOSURE_MASK)) + break; + + if (GDK_WINDOW_OBJECT (window)->bg_pixmap == GDK_NO_BG) + break; + if ((paintstruct.rcPaint.right == paintstruct.rcPaint.left) || (paintstruct.rcPaint.bottom == paintstruct.rcPaint.top)) break; @@ -2742,7 +2752,7 @@ gdk_event_translate (GdkEvent *event, expose_rect.width = paintstruct.rcPaint.right - paintstruct.rcPaint.left; expose_rect.height = paintstruct.rcPaint.bottom - paintstruct.rcPaint.top; - _gdk_window_process_expose (window, GetMessageTime (), &expose_rect); + _gdk_window_process_expose (window, msg->time, &expose_rect); return_val = FALSE; } @@ -2868,9 +2878,11 @@ gdk_event_translate (GdkEvent *event, { mmi->ptMaxTrackSize.x = window_impl->hint_max_width; mmi->ptMaxTrackSize.y = window_impl->hint_max_height; - - mmi->ptMaxSize.x = window_impl->hint_max_width; - mmi->ptMaxSize.y = window_impl->hint_max_height; + + /* kind of WM functionality, limit maximized size to screen */ + mmi->ptMaxPosition.x = 0; mmi->ptMaxPosition.y = 0; + mmi->ptMaxSize.x = MIN(window_impl->hint_max_width, gdk_screen_width ()); + mmi->ptMaxSize.y = MIN(window_impl->hint_max_height, gdk_screen_height ()); } break; @@ -3097,6 +3109,8 @@ void gdk_events_queue (void) { MSG msg; + GdkEvent *event; + GList *node; while (!gdk_event_queue_find_first () && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) @@ -3108,7 +3122,33 @@ gdk_events_queue (void) || (active_imm_msgpump_owner->lpVtbl->OnTranslateMessage) (active_imm_msgpump_owner, &msg) != S_OK) TranslateMessage (&msg); +#if 1 /* It was like this all the time */ DispatchMessage (&msg); +#else /* but this one is more similar to the X implementation. Any effect ? */ + event = gdk_event_new (); + + event->any.type = GDK_NOTHING; + event->any.window = NULL; + event->any.send_event = InSendMessage (); + + ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING; + + gdk_event_queue_append (event); + node = gdk_queued_tail; + + if (gdk_event_translate (event, &msg, NULL, NULL, FALSE)) + { + ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING; + } + else + { + gdk_event_queue_remove_link (node); + g_list_free_1 (node); + gdk_event_free (event); + DispatchMessage (&msg); + } + +#endif } } diff --git a/gdk/win32/gdkgeometry-win32.c b/gdk/win32/gdkgeometry-win32.c index d16ae5426a..373d6b596b 100644 --- a/gdk/win32/gdkgeometry-win32.c +++ b/gdk/win32/gdkgeometry-win32.c @@ -148,6 +148,10 @@ gdk_window_scroll (GdkWindow *window, if (GDK_WINDOW_DESTROYED (window)) return; + /* Move the current invalid region */ + if (obj->update_area) + gdk_region_offset (obj->update_area, dx, dy); + /* We can guffaw scroll if we are a child window, and the parent * does not extend beyond our edges. */ @@ -163,6 +167,47 @@ gdk_window_scroll (GdkWindow *window, if (!obj->children || !can_guffaw_scroll) { +#if 0 /* this may be the better way to do it, though there seems to + be an offset error in it */ + GList *tmp_list = obj->children; + int num_windows = g_list_length (tmp_list) + 1; + HDWP hWinPosInfo = BeginDeferWindowPos (num_windows); + + GDK_NOTE (MISC, + g_print ("gdk_window_scroll (%x, %d, %d), %d childs\n", + GDK_WINDOW_HWND (window), dx, dy, num_windows -1)); + if (!hWinPosInfo) + WIN32_API_FAILED ("BeginDeferWindowPos"); + else + { + + hWinPosInfo = + DeferWindowPos (hWinPosInfo, /* may change on return */ + GDK_WINDOW_HWND (window), + NULL, /* placement-order handle, ignored */ + obj->x + dx, obj->y + dy, /* new pos */ + 30, 20, /* new size, ignored */ + SWP_NOSIZE | SWP_NOZORDER); + + while (tmp_list) + { + GdkWindowObject * child = GDK_WINDOW_OBJECT (tmp_list->data); + + hWinPosInfo = + DeferWindowPos (hWinPosInfo, /* may change on return */ + GDK_WINDOW_HWND (child), + NULL, /* placement-order handle, ignored */ + child->x + dx, child->y + dy, /* new pos */ + 30, 20, /* new size, ignored */ + SWP_NOSIZE | SWP_NOZORDER); + + tmp_list = tmp_list->next; + } + + if (!EndDeferWindowPos (hWinPosInfo)) + WIN32_API_FAILED ("EndDeferWindowPos"); + } +#else /* Use ScrollWindowEx, then move any children later */ GList *tmp_list; @@ -203,6 +248,7 @@ gdk_window_scroll (GdkWindow *window, tmp_list = tmp_list->next; } +#endif } else { @@ -295,10 +341,10 @@ _gdk_window_move_resize_child (GdkWindow *window, new_y1 = impl->position_info.y + new_info.height + d_yoffset; } - if (!MoveWindow (GDK_WINDOW_HWND (window), + if (!SetWindowPos (GDK_WINDOW_HWND (window), NULL, new_x0, new_y0, new_x1 - new_x0, new_y1 - new_y0, - FALSE)) - WIN32_API_FAILED ("MoveWindow"); + SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW)) + WIN32_API_FAILED ("SetWindowPos"); tmp_list = obj->children; while (tmp_list) @@ -307,21 +353,25 @@ _gdk_window_move_resize_child (GdkWindow *window, tmp_list = tmp_list->next; } - GetClientRect (GDK_WINDOW_HWND (window), &rect); - - if (!MoveWindow (GDK_WINDOW_HWND (window), - new_x0 + dx, new_y0 + dy, - rect.right - rect.left, rect.bottom - rect.top, - FALSE)) - WIN32_API_FAILED ("MoveWindow"); + if (!SetWindowPos (GDK_WINDOW_HWND (window), NULL, + new_x0 + dx, new_y0 + dy, 0, 0, + SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOREDRAW)) + WIN32_API_FAILED ("SetWindowPos"); if (d_xoffset > 0 || d_yoffset > 0) gdk_window_queue_translation (window, MAX (d_xoffset, 0), MAX (d_yoffset, 0)); - if (!MoveWindow (GDK_WINDOW_HWND (window), + /* FIXME: + */ + if (new_info.x + new_info.width > 32767) + new_info.width = 32767 - new_info.x; + if (new_info.y + new_info.height > 32767) + new_info.height = 32767 - new_info.y; + + if (!SetWindowPos (GDK_WINDOW_HWND (window), NULL, new_info.x, new_info.y, new_info.width, new_info.height, - FALSE)) - WIN32_API_FAILED ("MoveWindow"); + SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW)) + WIN32_API_FAILED ("SetWindowPos"); if (impl->position_info.no_bg) gdk_window_tmp_reset_bg (window); @@ -353,28 +403,11 @@ _gdk_window_move_resize_child (GdkWindow *window, tmp_list = tmp_list->next; } - /* - * HB: Passing TRUE(=Redraw) to MoveWindow here fixes some - * redraw problems with (e.g. testgtk main buttons) - * scrolling. AFAIK the non flicker optimization would - * be done by the GDI anyway, if the window is SW_HIDE. - */ - if (is_resize) - { - if (!MoveWindow (GDK_WINDOW_HWND (window), + if (!SetWindowPos (GDK_WINDOW_HWND (window), NULL, new_info.x, new_info.y, new_info.width, new_info.height, - TRUE /*FALSE*/)) - WIN32_API_FAILED ("MoveWindow"); - } - else - { - GetClientRect (GDK_WINDOW_HWND (window), &rect); - if (!MoveWindow (GDK_WINDOW_HWND (window), - new_info.x, new_info.y, - rect.right - rect.left, rect.bottom - rect.top, - TRUE /*FALSE*/)) - WIN32_API_FAILED ("MoveWindow"); - } + SWP_NOACTIVATE | SWP_NOZORDER | + (is_resize ? 0 : SWP_NOSIZE))) + WIN32_API_FAILED ("SetWindowPos"); tmp_list = obj->children; while (tmp_list) @@ -610,10 +643,10 @@ gdk_window_premove (GdkWindow *window, new_y1 = impl->position_info.y + new_info.height + d_yoffset; } - if (!MoveWindow (GDK_WINDOW_HWND (window), + if (!SetWindowPos (GDK_WINDOW_HWND (window), NULL, new_x0, new_y0, new_x1 - new_x0, new_y1 - new_y0, - FALSE)) - WIN32_API_FAILED ("MoveWindow"); + SWP_NOREDRAW | SWP_NOZORDER | SWP_NOACTIVATE)) + WIN32_API_FAILED ("SetWindowPos"); } tmp_list = obj->children; @@ -654,10 +687,10 @@ gdk_window_postmove (GdkWindow *window, if (d_xoffset > 0 || d_yoffset > 0) gdk_window_queue_translation (window, MAX (d_xoffset, 0), MAX (d_yoffset, 0)); - if (!MoveWindow (GDK_WINDOW_HWND (window), + if (!SetWindowPos (GDK_WINDOW_HWND (window), NULL, new_info.x, new_info.y, new_info.width, new_info.height, - FALSE)) - WIN32_API_FAILED ("MoveWindow"); + SWP_NOREDRAW | SWP_NOZORDER | SWP_NOACTIVATE)) + WIN32_API_FAILED ("SetWindowPos"); } if (!impl->position_info.mapped && new_info.mapped && GDK_WINDOW_IS_MAPPED (obj)) @@ -701,7 +734,7 @@ gboolean _gdk_windowing_window_queue_antiexpose (GdkWindow *window, GdkRegion *area) { -#if 0 +#if 1 GdkWindowQueueItem *item = g_new (GdkWindowQueueItem, 1); item->window = window; diff --git a/gdk/win32/gdkselection-win32.c b/gdk/win32/gdkselection-win32.c index bf5733c8b8..fd85b80322 100644 --- a/gdk/win32/gdkselection-win32.c +++ b/gdk/win32/gdkselection-win32.c @@ -95,7 +95,12 @@ gdk_selection_owner_set (GdkWindow *owner, g_free (sel_name))); if (selection != gdk_clipboard_atom) - return FALSE; + { + if (!owner) + return FALSE; + gdk_sel_prop_store (owner, selection, 0, 0, 0); + return TRUE; + } if (owner != NULL) { @@ -143,23 +148,52 @@ gdk_selection_owner_set (GdkWindow *owner, return TRUE; } +/* callback for g_hash_table_for_each */ +typedef struct { + GdkAtom atom; + GdkNativeWindow hwnd; +} SelectionAndHwnd; + +static void +window_from_selection (gpointer key, + gpointer value, + gpointer user_data) +{ + GdkSelProp *selprop = (GdkSelProp *)value; + SelectionAndHwnd *sah = (SelectionAndHwnd *) user_data; + + if (selprop->type == sah->atom) + sah->hwnd = *(GdkNativeWindow*) key; +} + GdkWindow* gdk_selection_owner_get (GdkAtom selection) { GdkWindow *window; gchar *sel_name; -#if 1 +#if 0 /* XXX Hmm, gtk selections seem to work best with this. This causes * gtk to always get the clipboard contents from Windows, and not * from the editable's own stashed-away copy. */ return NULL; #else + /* HB: The above is no longer true with recent changes to get + * inter-app drag&drop working ... + */ if (selection != gdk_clipboard_atom) - window = NULL; + { + SelectionAndHwnd sah; + sah.atom = selection; + sah.hwnd = 0; + + g_hash_table_foreach (sel_prop_table, window_from_selection, &sah); + + window = gdk_win32_handle_table_lookup (sah.hwnd); + } else - window = gdk_win32_handle_table_lookup (GetClipboardOwner ()); + window = gdk_win32_handle_table_lookup ((GdkNativeWindow) GetClipboardOwner ()); #endif @@ -372,7 +406,10 @@ gdk_selection_send_notify (guint32 requestor, * always return NULL, it works. Sigh. */ - SendMessage ((HWND) requestor, gdk_selection_clear_msg, selection, 0); + SendMessage ((HWND) requestor, + gdk_selection_clear_msg, + selection, + target); } gint diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c index 1d6e7deeb4..75ce99dc9e 100644 --- a/gdk/win32/gdkwindow-win32.c +++ b/gdk/win32/gdkwindow-win32.c @@ -805,14 +805,14 @@ gdk_window_destroy_notify (GdkWindow *window) gdk_drawable_unref (window); } -void -gdk_window_show (GdkWindow *window) +static void +show_window_internal (GdkWindow *window, + gboolean raise) { GdkWindowObject *private; - g_return_if_fail (GDK_IS_WINDOW (window)); - - private = (GdkWindowObject*) window; + private = GDK_WINDOW_OBJECT (window); + if (!private->destroyed) { GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n", @@ -852,7 +852,8 @@ gdk_window_show (GdkWindow *window) } if (parent == gdk_parent_root) SetForegroundWindow (GDK_WINDOW_HWND (window)); - BringWindowToTop (GDK_WINDOW_HWND (window)); + if (raise) + BringWindowToTop (GDK_WINDOW_HWND (window)); #if 0 ShowOwnedPopups (GDK_WINDOW_HWND (window), TRUE); #endif @@ -862,6 +863,22 @@ gdk_window_show (GdkWindow *window) } void +gdk_window_show_unraised (GdkWindow *window) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + show_window_internal (window, FALSE); +} + +void +gdk_window_show (GdkWindow *window) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + show_window_internal (window, TRUE); +} + +void gdk_window_hide (GdkWindow *window) { GdkWindowObject *private; @@ -920,7 +937,19 @@ gdk_window_move (GdkWindow *window, impl = GDK_WINDOW_IMPL_WIN32 (private->impl); - gdk_window_move_resize (window, x, y, impl->width, impl->height); + if (!GDK_WINDOW_DESTROYED (window)) + { + if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD) + _gdk_window_move_resize_child (window, x, y, + impl->width, impl->height); + else + { + if (!SetWindowPos (GDK_WINDOW_HWND (window), NULL, + x, y, impl->width, impl->height, + SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER)) + WIN32_API_FAILED ("SetWindowPos"); + } + } } void @@ -942,13 +971,12 @@ gdk_window_resize (GdkWindow *window, impl = GDK_WINDOW_IMPL_WIN32 (private->impl); - if (!private->destroyed) + if (!GDK_WINDOW_DESTROYED (window)) { - GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n", - (guint) GDK_WINDOW_HWND (window), - width, height)); - - if (GDK_WINDOW_TYPE (private) != GDK_WINDOW_CHILD) + if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD) + _gdk_window_move_resize_child (window, private->x, private->y, + width, height); + else { POINT pt; RECT rect; @@ -972,22 +1000,12 @@ gdk_window_resize (GdkWindow *window, y = rect.top; width = rect.right - rect.left; height = rect.bottom - rect.top; + if (!SetWindowPos (GDK_WINDOW_HWND (window), NULL, + x, y, width, height, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER)) + WIN32_API_FAILED ("SetWindowPos"); } - else - { - x = private->x; - y = private->y; - impl->width = width; - impl->height = height; - } - private->resize_count += 1; - - GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n", - (guint) GDK_WINDOW_HWND (window), - width, height, x, y)); - if (!MoveWindow (GDK_WINDOW_HWND (window), x, y, width, height, TRUE)) - WIN32_API_FAILED ("MoveWindow"); } } @@ -1035,15 +1053,15 @@ gdk_window_move_resize (GdkWindow *window, if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle)) WIN32_API_FAILED ("AdjustWindowRectEx"); - GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%ldx%ld@+%ld+%ld)\n", + GDK_NOTE (MISC, g_print ("...SetWindowPos(%#x,%ldx%ld@+%ld+%ld)\n", (guint) GDK_WINDOW_HWND (window), rect.right - rect.left, rect.bottom - rect.top, rect.left, rect.top)); - if (!MoveWindow (GDK_WINDOW_HWND (window), - rect.left, rect.top, - rect.right - rect.left, rect.bottom - rect.top, - TRUE)) - WIN32_API_FAILED ("MoveWindow"); + if (!SetWindowPos (GDK_WINDOW_HWND (window), NULL, + rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, + SWP_NOACTIVATE | SWP_NOZORDER)) + WIN32_API_FAILED ("SetWindowPos"); } } } @@ -1509,6 +1527,10 @@ gdk_window_set_transient_for (GdkWindow *window, #if 0 /* not sure if we want to do this, clipping to parent size! */ if (!SetParent (window_id, parent_id)) WIN32_API_FAILED ("SetParent"); +#else /* make the modal window topmost instead */ + if (!SetWindowPos (window_id, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE)) + WIN32_API_FAILED ("SetWindowPos"); #endif if (!RedrawWindow (window_id, NULL, NULL, |