]> Pileus Git - ~andy/gtk/blob - gdk/quartz/GdkQuartzWindow.c
Add escape to the list of special keys, to get the escape key working.
[~andy/gtk] / gdk / quartz / GdkQuartzWindow.c
1 /* GdkQuartzWindow.m
2  *
3  * Copyright (C) 2005 Imendio AB
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21
22 #import "GdkQuartzWindow.h"
23 #include "gdkwindow-quartz.h"
24 #include "gdkprivate-quartz.h"
25
26 @implementation GdkQuartzWindow
27
28 -(BOOL)windowShouldClose:(id)sender
29 {
30   GdkWindow *window = [[self contentView] gdkWindow];
31   GdkEvent *event;
32
33   event = gdk_event_new (GDK_DELETE);
34
35   event->any.window = g_object_ref (window);
36   event->any.send_event = FALSE;
37
38   _gdk_event_queue_append (gdk_display_get_default (), event);
39
40   return NO;
41 }
42
43 -(void)windowDidMiniaturize:(NSNotification *)aNotification
44 {
45   GdkWindow *window = [[self contentView] gdkWindow];
46
47   gdk_synthesize_window_state (window, 0, 
48                                GDK_WINDOW_STATE_ICONIFIED);
49 }
50
51 -(void)windowDidDeminiaturize:(NSNotification *)aNotification
52 {
53   GdkWindow *window = [[self contentView] gdkWindow];
54
55   gdk_synthesize_window_state (window, GDK_WINDOW_STATE_ICONIFIED, 0);
56 }
57
58 -(void)windowDidBecomeKey:(NSNotification *)aNotification
59 {
60   GdkWindow *window = [[self contentView] gdkWindow];
61
62   _gdk_quartz_update_focus_window (window);
63 }
64
65 -(void)windowDidMove:(NSNotification *)aNotification
66 {
67   NSRect content_rect = [self contentRectForFrameRect:[self frame]];
68   GdkWindow *window = [[self contentView] gdkWindow];
69   GdkWindowObject *private = (GdkWindowObject *)window;
70   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
71   GdkEvent *event;
72
73   private->x = content_rect.origin.x;
74   private->y = _gdk_quartz_get_inverted_screen_y (content_rect.origin.y) - impl->height;
75
76   /* Synthesize a configure event */
77   event = gdk_event_new (GDK_CONFIGURE);
78   event->configure.window = g_object_ref (window);
79   event->configure.x = private->x;
80   event->configure.y = private->y;
81   event->configure.width = impl->width;
82   event->configure.height = impl->height;
83
84   _gdk_event_queue_append (gdk_display_get_default (), event);
85 }
86
87 -(void)windowDidResize:(NSNotification *)aNotification
88 {
89   NSRect content_rect = [self contentRectForFrameRect:[self frame]];
90   GdkWindow *window = [[self contentView] gdkWindow];
91   GdkWindowObject *private = (GdkWindowObject *)window;
92   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
93   GdkEvent *event;
94
95   impl->width = content_rect.size.width;
96   impl->height = content_rect.size.height;
97
98   /* Synthesize a configure event */
99
100   event = gdk_event_new (GDK_CONFIGURE);
101   event->configure.window = g_object_ref (window);
102   event->configure.x = private->x;
103   event->configure.y = private->y;
104   event->configure.width = impl->width;
105   event->configure.height = impl->height;
106
107   _gdk_event_queue_append (gdk_display_get_default (), event);
108
109   /* Update tracking rectangle */
110   [[self contentView] removeTrackingRect:impl->tracking_rect];
111   impl->tracking_rect = [impl->view addTrackingRect:NSMakeRect(0, 0, impl->width, impl->height) 
112                                               owner:impl->view
113                                            userData:nil
114                                        assumeInside:NO];
115 }
116
117 -(id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag
118 {
119   self = [super initWithContentRect:contentRect
120                           styleMask:styleMask
121                             backing:backingType
122                               defer:flag];
123
124
125   /* A possible modification here would be to only accept mouse moved events
126    * if any of the child GdkWindows are interested in mouse moved events.
127    */
128   [self setAcceptsMouseMovedEvents:YES];
129
130   [self setDelegate:self];
131   [self setReleasedWhenClosed:YES];
132
133   return self;
134 }
135
136 -(BOOL)canBecomeMainWindow
137 {
138   return YES;
139 }
140
141 -(BOOL)canBecomeKeyWindow
142 {
143   return YES;
144 }
145
146 static GdkDragContext *current_context = NULL;
147
148 static GdkDragAction
149 drag_operation_to_drag_action (NSDragOperation operation)
150 {
151   GdkDragAction result = 0;
152
153   if (operation & NSDragOperationGeneric)
154     result |= GDK_ACTION_COPY;
155
156   return result;
157 }
158
159 static NSDragOperation
160 drag_action_to_drag_operation (GdkDragAction action)
161 {
162   NSDragOperation result = 0;
163
164   if (action & GDK_ACTION_COPY)
165     result |= NSDragOperationCopy;
166
167   return result;
168 }
169
170 static void
171 update_context_from_dragging_info (id <NSDraggingInfo> sender)
172 {
173   g_assert (current_context != NULL);
174
175   GDK_DRAG_CONTEXT_PRIVATE (current_context)->dragging_info = sender;
176   current_context->suggested_action = drag_operation_to_drag_action ([sender draggingSourceOperationMask]);
177 }
178
179 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
180 {
181   GdkEvent event;
182
183   if (current_context)
184     g_object_unref (current_context);
185   
186   current_context = gdk_drag_context_new ();
187   update_context_from_dragging_info (sender);
188
189   event.dnd.type = GDK_DRAG_ENTER;
190   event.dnd.window = g_object_ref ([[self contentView] gdkWindow]);
191   event.dnd.send_event = FALSE;
192   event.dnd.context = current_context;
193   event.dnd.time = GDK_CURRENT_TIME;
194
195   (*_gdk_event_func) (&event, _gdk_event_data);
196
197   return NSDragOperationNone;
198 }
199
200 - (void)draggingEnded:(id <NSDraggingInfo>)sender
201 {
202   g_object_unref (current_context);
203   current_context = NULL;
204 }
205
206 - (void)draggingExited:(id <NSDraggingInfo>)sender
207 {
208   GdkEvent event;
209   
210   event.dnd.type = GDK_DRAG_LEAVE;
211   event.dnd.window = g_object_ref ([[self contentView] gdkWindow]);
212   event.dnd.send_event = FALSE;
213   event.dnd.context = current_context;
214   event.dnd.time = GDK_CURRENT_TIME;
215
216   (*_gdk_event_func) (&event, _gdk_event_data);
217   
218   g_object_unref (current_context);
219   current_context = NULL;
220 }
221
222 - (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
223 {
224   NSPoint point = [sender draggingLocation];
225   NSPoint screen_point = [self convertBaseToScreen:point];
226   GdkEvent event;
227
228   update_context_from_dragging_info (sender);
229
230   event.dnd.type = GDK_DRAG_MOTION;
231   event.dnd.window = g_object_ref ([[self contentView] gdkWindow]);
232   event.dnd.send_event = FALSE;
233   event.dnd.context = current_context;
234   event.dnd.time = GDK_CURRENT_TIME;
235   event.dnd.x_root = screen_point.x;
236   event.dnd.y_root = _gdk_quartz_get_inverted_screen_y (screen_point.y);
237
238   (*_gdk_event_func) (&event, _gdk_event_data);
239
240   g_object_unref (event.dnd.window);
241
242   return drag_action_to_drag_operation (current_context->action);
243 }
244
245 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
246 {
247   NSPoint point = [sender draggingLocation];
248   NSPoint screen_point = [self convertBaseToScreen:point];
249   GdkEvent event;
250
251   update_context_from_dragging_info (sender);
252
253   event.dnd.type = GDK_DROP_START;
254   event.dnd.window = g_object_ref ([[self contentView] gdkWindow]);
255   event.dnd.send_event = FALSE;
256   event.dnd.context = current_context;
257   event.dnd.time = GDK_CURRENT_TIME;
258   event.dnd.x_root = screen_point.x;
259   event.dnd.y_root = _gdk_quartz_get_inverted_screen_y (screen_point.y);
260
261   (*_gdk_event_func) (&event, _gdk_event_data);
262
263   g_object_unref (event.dnd.window);
264
265   g_object_unref (current_context);
266   current_context = NULL;
267
268   return YES;
269 }
270
271 - (BOOL)wantsPeriodicDraggingUpdates
272 {
273   return NO;
274 }
275
276 - (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
277 {
278   GdkEvent event;
279
280   g_assert (_gdk_quartz_drag_source_context != NULL);
281
282   event.dnd.type = GDK_DROP_FINISHED;
283   event.dnd.window = g_object_ref ([[self contentView] gdkWindow]);
284   event.dnd.send_event = FALSE;
285   event.dnd.context = _gdk_quartz_drag_source_context;
286
287   (*_gdk_event_func) (&event, _gdk_event_data);
288
289   g_object_unref (event.dnd.window);
290
291   g_object_unref (_gdk_quartz_drag_source_context);
292   _gdk_quartz_drag_source_context = NULL;
293 }
294
295 @end