Blame gdk/quartz/GdkQuartzWindow.c

Packit 98cdb6
/* GdkQuartzWindow.m
Packit 98cdb6
 *
Packit 98cdb6
 * Copyright (C) 2005-2007 Imendio AB
Packit 98cdb6
 *
Packit 98cdb6
 * This library is free software; you can redistribute it and/or
Packit 98cdb6
 * modify it under the terms of the GNU Lesser General Public
Packit 98cdb6
 * License as published by the Free Software Foundation; either
Packit 98cdb6
 * version 2 of the License, or (at your option) any later version.
Packit 98cdb6
 *
Packit 98cdb6
 * This library is distributed in the hope that it will be useful,
Packit 98cdb6
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 98cdb6
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 98cdb6
 * Lesser General Public License for more details.
Packit 98cdb6
 *
Packit 98cdb6
 * You should have received a copy of the GNU Lesser General Public
Packit 98cdb6
 * License along with this library; if not, write to the
Packit 98cdb6
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit 98cdb6
 * Boston, MA 02111-1307, USA.
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
#import "GdkQuartzWindow.h"
Packit 98cdb6
#include "gdkwindow-quartz.h"
Packit 98cdb6
#include "gdkprivate-quartz.h"
Packit 98cdb6
Packit 98cdb6
@implementation GdkQuartzWindow
Packit 98cdb6
Packit 98cdb6
- (void)windowWillClose:(NSNotification*)notification
Packit 98cdb6
{
Packit 98cdb6
  // Clears the delegate when window is going to be closed; since EL
Packit 98cdb6
  // Capitan it is possible that the methods of delegate would get
Packit 98cdb6
  // called after the window has been closed.
Packit 98cdb6
  [self setDelegate:nil];
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(BOOL)windowShouldClose:(id)sender
Packit 98cdb6
{
Packit 98cdb6
  GdkWindow *window = [[self contentView] gdkWindow];
Packit 98cdb6
  GdkEvent *event;
Packit 98cdb6
Packit 98cdb6
  event = gdk_event_new (GDK_DELETE);
Packit 98cdb6
Packit 98cdb6
  event->any.window = g_object_ref (window);
Packit 98cdb6
  event->any.send_event = FALSE;
Packit 98cdb6
Packit 98cdb6
  _gdk_event_queue_append (gdk_display_get_default (), event);
Packit 98cdb6
Packit 98cdb6
  return NO;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(void)windowWillMiniaturize:(NSNotification *)aNotification
Packit 98cdb6
{
Packit 98cdb6
  GdkWindow *window = [[self contentView] gdkWindow];
Packit 98cdb6
Packit 98cdb6
  _gdk_quartz_window_detach_from_parent (window);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(void)windowDidMiniaturize:(NSNotification *)aNotification
Packit 98cdb6
{
Packit 98cdb6
  GdkWindow *window = [[self contentView] gdkWindow];
Packit 98cdb6
Packit 98cdb6
  gdk_synthesize_window_state (window, 0, 
Packit 98cdb6
			       GDK_WINDOW_STATE_ICONIFIED);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(void)windowDidDeminiaturize:(NSNotification *)aNotification
Packit 98cdb6
{
Packit 98cdb6
  GdkWindow *window = [[self contentView] gdkWindow];
Packit 98cdb6
Packit 98cdb6
  _gdk_quartz_window_attach_to_parent (window);
Packit 98cdb6
Packit 98cdb6
  gdk_synthesize_window_state (window, GDK_WINDOW_STATE_ICONIFIED, 0);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(void)windowDidBecomeKey:(NSNotification *)aNotification
Packit 98cdb6
{
Packit 98cdb6
  GdkWindow *window = [[self contentView] gdkWindow];
Packit 98cdb6
Packit 98cdb6
  _gdk_quartz_events_update_focus_window (window, TRUE);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(void)windowDidResignKey:(NSNotification *)aNotification
Packit 98cdb6
{
Packit 98cdb6
  GdkWindow *window = [[self contentView] gdkWindow];
Packit 98cdb6
Packit 98cdb6
  _gdk_quartz_events_update_focus_window (window, FALSE);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(void)windowDidBecomeMain:(NSNotification *)aNotification
Packit 98cdb6
{
Packit 98cdb6
  GdkWindow *window = [[self contentView] gdkWindow];
Packit 98cdb6
Packit 98cdb6
  if (![self isVisible])
Packit 98cdb6
    {
Packit 98cdb6
      /* Note: This is a hack needed because for unknown reasons, hidden
Packit 98cdb6
       * windows get shown when clicking the dock icon when the application
Packit 98cdb6
       * is not already active.
Packit 98cdb6
       */
Packit 98cdb6
      [self orderOut:nil];
Packit 98cdb6
      return;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  _gdk_quartz_window_did_become_main (window);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(void)windowDidResignMain:(NSNotification *)aNotification
Packit 98cdb6
{
Packit 98cdb6
  GdkWindow *window;
Packit 98cdb6
Packit 98cdb6
  window = [[self contentView] gdkWindow];
Packit 98cdb6
  _gdk_quartz_window_did_resign_main (window);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* Used in combination with NSLeftMouseUp in sendEvent to keep track
Packit 98cdb6
 * of when the window is being moved with the mouse.
Packit 98cdb6
 */
Packit 98cdb6
-(void)windowWillMove:(NSNotification *)aNotification
Packit 98cdb6
{
Packit 98cdb6
  inMove = YES;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(void)sendEvent:(NSEvent *)event
Packit 98cdb6
{
Packit 98cdb6
  switch ([event type])
Packit 98cdb6
    {
Packit 98cdb6
    case NSLeftMouseUp:
Packit 98cdb6
    {
Packit 98cdb6
      double time = ((double)[event timestamp]) * 1000.0;
Packit 98cdb6
Packit 98cdb6
      _gdk_quartz_events_break_all_grabs (time);
Packit 98cdb6
      inManualMove = NO;
Packit 98cdb6
      inManualResize = NO;
Packit 98cdb6
      inMove = NO;
Packit 98cdb6
      break;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
    case NSLeftMouseDragged:
Packit 98cdb6
      if ([self trackManualMove] || [self trackManualResize])
Packit 98cdb6
        return;
Packit 98cdb6
      break;
Packit 98cdb6
Packit 98cdb6
    default:
Packit 98cdb6
      break;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  [super sendEvent:event];
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(BOOL)isInMove
Packit 98cdb6
{
Packit 98cdb6
  return inMove;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(void)checkSendEnterNotify
Packit 98cdb6
{
Packit 98cdb6
  GdkWindow *window = [[self contentView] gdkWindow];
Packit 98cdb6
  GdkWindowObject *private = (GdkWindowObject *)window;
Packit 98cdb6
  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
Packit 98cdb6
Packit 98cdb6
  /* When a new window has been created, and the mouse
Packit 98cdb6
   * is in the window area, we will not receive an NSMouseEntered
Packit 98cdb6
   * event.  Therefore, we synthesize an enter notify event manually.
Packit 98cdb6
   */
Packit 98cdb6
  if (!initialPositionKnown)
Packit 98cdb6
    {
Packit 98cdb6
      initialPositionKnown = YES;
Packit 98cdb6
Packit 98cdb6
      if (NSPointInRect ([NSEvent mouseLocation], [self frame]))
Packit 98cdb6
        {
Packit 98cdb6
          NSEvent *event;
Packit 98cdb6
Packit 98cdb6
          event = [NSEvent enterExitEventWithType: NSMouseEntered
Packit 98cdb6
                                         location: [self mouseLocationOutsideOfEventStream]
Packit 98cdb6
                                    modifierFlags: 0
Packit 98cdb6
                                        timestamp: [[NSApp currentEvent] timestamp]
Packit 98cdb6
                                     windowNumber: [impl->toplevel windowNumber]
Packit 98cdb6
                                          context: NULL
Packit 98cdb6
                                      eventNumber: 0
Packit 98cdb6
                                   trackingNumber: [impl->view trackingRect]
Packit 98cdb6
                                         userData: nil];
Packit 98cdb6
Packit 98cdb6
          [NSApp postEvent:event atStart:NO];
Packit 98cdb6
        }
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* Always update both the position and size. Certain resize operations
Packit 98cdb6
 * (e.g. going fullscreen) also move the origin of the window. Move
Packit 98cdb6
 * notifications sometimes also indicate a different window size (for
Packit 98cdb6
 * example if the window size requested in the configure request was not
Packit 98cdb6
 * fully granted).
Packit 98cdb6
 */
Packit 98cdb6
-(void)handleDidMoveResize
Packit 98cdb6
{
Packit 98cdb6
  NSRect content_rect = [self contentRectForFrameRect:[self frame]];
Packit 98cdb6
  GdkWindow *window = [[self contentView] gdkWindow];
Packit 98cdb6
  GdkWindowObject *private = (GdkWindowObject *)window;
Packit 98cdb6
  GdkEvent *event;
Packit 98cdb6
Packit 98cdb6
  private->width = content_rect.size.width;
Packit 98cdb6
  private->height = content_rect.size.height;
Packit 98cdb6
Packit 98cdb6
  _gdk_quartz_window_update_position (window);
Packit 98cdb6
Packit 98cdb6
  [[self contentView] setFrame:NSMakeRect (0, 0, private->width, private->height)];
Packit 98cdb6
Packit 98cdb6
  _gdk_window_update_size (window);
Packit 98cdb6
Packit 98cdb6
  /* Synthesize a configure event */
Packit 98cdb6
  event = gdk_event_new (GDK_CONFIGURE);
Packit 98cdb6
  event->configure.window = g_object_ref (window);
Packit 98cdb6
  event->configure.x = private->x;
Packit 98cdb6
  event->configure.y = private->y;
Packit 98cdb6
  event->configure.width = private->width;
Packit 98cdb6
  event->configure.height = private->height;
Packit 98cdb6
Packit 98cdb6
  _gdk_event_queue_append (gdk_display_get_default (), event);
Packit 98cdb6
Packit 98cdb6
  [self checkSendEnterNotify];
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(void)windowDidMove:(NSNotification *)aNotification
Packit 98cdb6
{
Packit 98cdb6
  [self handleDidMoveResize];
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(void)windowDidResize:(NSNotification *)aNotification
Packit 98cdb6
{
Packit 98cdb6
  [self handleDidMoveResize];
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag screen:(NSScreen *)screen
Packit 98cdb6
{
Packit 98cdb6
  self = [super initWithContentRect:contentRect
Packit 98cdb6
	                  styleMask:styleMask
Packit 98cdb6
	                    backing:backingType
Packit 98cdb6
	                      defer:flag
Packit 98cdb6
                             screen:screen];
Packit 98cdb6
Packit 98cdb6
  [self setAcceptsMouseMovedEvents:YES];
Packit 98cdb6
  [self setDelegate:self];
Packit 98cdb6
  [self setReleasedWhenClosed:YES];
Packit 98cdb6
Packit 98cdb6
  return self;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(BOOL)canBecomeMainWindow
Packit 98cdb6
{
Packit 98cdb6
  GdkWindow *window = [[self contentView] gdkWindow];
Packit 98cdb6
  GdkWindowObject *private = (GdkWindowObject *)window;
Packit 98cdb6
  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
Packit 98cdb6
Packit 98cdb6
  switch (impl->type_hint)
Packit 98cdb6
    {
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_NORMAL:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_DIALOG:
Packit 98cdb6
      return YES;
Packit 98cdb6
      
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_MENU:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_TOOLBAR:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_UTILITY:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_DOCK:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_DESKTOP:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_TOOLTIP:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_COMBO:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_DND:
Packit 98cdb6
      return NO;
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  return YES;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(BOOL)canBecomeKeyWindow
Packit 98cdb6
{
Packit 98cdb6
  GdkWindow *window = [[self contentView] gdkWindow];
Packit 98cdb6
  GdkWindowObject *private = (GdkWindowObject *)window;
Packit 98cdb6
  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
Packit 98cdb6
Packit 98cdb6
  if (!private->accept_focus)
Packit 98cdb6
    return NO;
Packit 98cdb6
Packit 98cdb6
  /* Popup windows should not be able to get focused in the window
Packit 98cdb6
   * manager sense, it's only handled through grabs.
Packit 98cdb6
   */
Packit 98cdb6
  if (private->window_type == GDK_WINDOW_TEMP)
Packit 98cdb6
    return NO;
Packit 98cdb6
Packit 98cdb6
  switch (impl->type_hint)
Packit 98cdb6
    {
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_NORMAL:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_DIALOG:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_MENU:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_TOOLBAR:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_UTILITY:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_DOCK:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_DESKTOP:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_COMBO:
Packit 98cdb6
      return YES;
Packit 98cdb6
      
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_TOOLTIP:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
Packit 98cdb6
    case GDK_WINDOW_TYPE_HINT_DND:
Packit 98cdb6
      return NO;
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  return YES;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
- (void)showAndMakeKey:(BOOL)makeKey
Packit 98cdb6
{
Packit 98cdb6
  GdkWindow *window = [[self contentView] gdkWindow];
Packit 98cdb6
  GdkWindowObject *private = (GdkWindowObject *)window;
Packit 98cdb6
  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
Packit 98cdb6
Packit 98cdb6
  inShowOrHide = YES;
Packit 98cdb6
Packit 98cdb6
  if (makeKey)
Packit 98cdb6
    [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
Packit 98cdb6
  else
Packit 98cdb6
    [impl->toplevel orderFront:nil];
Packit 98cdb6
Packit 98cdb6
  inShowOrHide = NO;
Packit 98cdb6
Packit 98cdb6
  [self checkSendEnterNotify];
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
- (void)hide
Packit 98cdb6
{
Packit 98cdb6
  GdkWindow *window = [[self contentView] gdkWindow];
Packit 98cdb6
  GdkWindowObject *private = (GdkWindowObject *)window;
Packit 98cdb6
  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
Packit 98cdb6
Packit 98cdb6
  inShowOrHide = YES;
Packit 98cdb6
  [impl->toplevel orderOut:nil];
Packit 98cdb6
  inShowOrHide = NO;
Packit 98cdb6
Packit 98cdb6
  initialPositionKnown = NO;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
- (BOOL)trackManualMove
Packit 98cdb6
{
Packit 98cdb6
  NSPoint currentLocation;
Packit 98cdb6
  NSPoint newOrigin;
Packit 98cdb6
  NSRect screenFrame = [[NSScreen mainScreen] visibleFrame];
Packit 98cdb6
  NSRect windowFrame = [self frame];
Packit 98cdb6
Packit 98cdb6
  if (!inManualMove)
Packit 98cdb6
    return NO;
Packit 98cdb6
Packit 98cdb6
  currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
Packit 98cdb6
  newOrigin.x = currentLocation.x - initialMoveLocation.x;
Packit 98cdb6
  newOrigin.y = currentLocation.y - initialMoveLocation.y;
Packit 98cdb6
Packit 98cdb6
  /* Clamp vertical position to below the menu bar. */
Packit 98cdb6
  if (newOrigin.y + windowFrame.size.height > screenFrame.origin.y + screenFrame.size.height)
Packit 98cdb6
    newOrigin.y = screenFrame.origin.y + screenFrame.size.height - windowFrame.size.height;
Packit 98cdb6
Packit 98cdb6
  [self setFrameOrigin:newOrigin];
Packit 98cdb6
Packit 98cdb6
  return YES;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(void)beginManualMove
Packit 98cdb6
{
Packit 98cdb6
  NSRect frame = [self frame];
Packit 98cdb6
Packit 98cdb6
  if (inMove || inManualMove || inManualResize)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  inManualMove = YES;
Packit 98cdb6
Packit 98cdb6
  initialMoveLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
Packit 98cdb6
  initialMoveLocation.x -= frame.origin.x;
Packit 98cdb6
  initialMoveLocation.y -= frame.origin.y;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
- (BOOL)trackManualResize
Packit 98cdb6
{
Packit 98cdb6
  NSPoint currentLocation;
Packit 98cdb6
  NSRect newFrame;
Packit 98cdb6
  float dx, dy;
Packit 98cdb6
  NSSize min_size;
Packit 98cdb6
Packit 98cdb6
  if (!inManualResize || inTrackManualResize)
Packit 98cdb6
    return NO;
Packit 98cdb6
Packit 98cdb6
  inTrackManualResize = YES;
Packit 98cdb6
Packit 98cdb6
  currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
Packit 98cdb6
  currentLocation.x -= initialResizeFrame.origin.x;
Packit 98cdb6
  currentLocation.y -= initialResizeFrame.origin.y;
Packit 98cdb6
Packit 98cdb6
  dx = currentLocation.x - initialResizeLocation.x;
Packit 98cdb6
  dy = -(currentLocation.y - initialResizeLocation.y);
Packit 98cdb6
Packit 98cdb6
  newFrame = initialResizeFrame;
Packit 98cdb6
  newFrame.size.width = initialResizeFrame.size.width + dx;
Packit 98cdb6
  newFrame.size.height = initialResizeFrame.size.height + dy;
Packit 98cdb6
Packit 98cdb6
  min_size = [self contentMinSize];
Packit 98cdb6
  if (newFrame.size.width < min_size.width)
Packit 98cdb6
    newFrame.size.width = min_size.width;
Packit 98cdb6
  if (newFrame.size.height < min_size.height)
Packit 98cdb6
    newFrame.size.height = min_size.height;
Packit 98cdb6
Packit 98cdb6
  /* We could also apply aspect ratio:
Packit 98cdb6
     newFrame.size.height = newFrame.size.width / [self aspectRatio].width * [self aspectRatio].height;
Packit 98cdb6
  */
Packit 98cdb6
Packit 98cdb6
  dy = newFrame.size.height - initialResizeFrame.size.height;
Packit 98cdb6
Packit 98cdb6
  newFrame.origin.x = initialResizeFrame.origin.x;
Packit 98cdb6
  newFrame.origin.y = initialResizeFrame.origin.y - dy;
Packit 98cdb6
Packit 98cdb6
  [self setFrame:newFrame display:YES];
Packit 98cdb6
Packit 98cdb6
  /* Let the resizing be handled by GTK+. */
Packit 98cdb6
  if (g_main_context_pending (NULL))
Packit 98cdb6
    g_main_context_iteration (NULL, FALSE);
Packit 98cdb6
Packit 98cdb6
  inTrackManualResize = NO;
Packit 98cdb6
Packit 98cdb6
  return YES;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(BOOL)isInManualResize
Packit 98cdb6
{
Packit 98cdb6
  return inManualResize;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
-(void)beginManualResize
Packit 98cdb6
{
Packit 98cdb6
  if (inMove || inManualMove || inManualResize)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  inManualResize = YES;
Packit 98cdb6
Packit 98cdb6
  initialResizeFrame = [self frame];
Packit 98cdb6
  initialResizeLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]];
Packit 98cdb6
  initialResizeLocation.x -= initialResizeFrame.origin.x;
Packit 98cdb6
  initialResizeLocation.y -= initialResizeFrame.origin.y;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
static GdkDragContext *current_context = NULL;
Packit 98cdb6
Packit 98cdb6
static GdkDragAction
Packit 98cdb6
drag_operation_to_drag_action (NSDragOperation operation)
Packit 98cdb6
{
Packit 98cdb6
  GdkDragAction result = 0;
Packit 98cdb6
Packit 98cdb6
  /* GDK and Quartz drag operations do not map 1:1.
Packit 98cdb6
   * This mapping represents about the best that we
Packit 98cdb6
   * can come up.
Packit 98cdb6
   *
Packit 98cdb6
   * Note that NSDragOperationPrivate and GDK_ACTION_PRIVATE
Packit 98cdb6
   * have almost opposite meanings: the GDK one means that the
Packit 98cdb6
   * destination is solely responsible for the action; the Quartz
Packit 98cdb6
   * one means that the source and destination will agree
Packit 98cdb6
   * privately on the action. NSOperationGeneric is close in meaning
Packit 98cdb6
   * to GDK_ACTION_PRIVATE but there is a problem: it will be
Packit 98cdb6
   * sent for any ordinary drag, and likely not understood
Packit 98cdb6
   * by any intra-widget drag (since the source & dest are the
Packit 98cdb6
   * same).
Packit 98cdb6
   */
Packit 98cdb6
Packit 98cdb6
  if (operation & NSDragOperationGeneric)
Packit 98cdb6
    result |= GDK_ACTION_MOVE;
Packit 98cdb6
  if (operation & NSDragOperationCopy)
Packit 98cdb6
    result |= GDK_ACTION_COPY;
Packit 98cdb6
  if (operation & NSDragOperationMove)
Packit 98cdb6
    result |= GDK_ACTION_MOVE;
Packit 98cdb6
  if (operation & NSDragOperationLink)
Packit 98cdb6
    result |= GDK_ACTION_LINK;
Packit 98cdb6
Packit 98cdb6
  return result;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static NSDragOperation
Packit 98cdb6
drag_action_to_drag_operation (GdkDragAction action)
Packit 98cdb6
{
Packit 98cdb6
  NSDragOperation result = 0;
Packit 98cdb6
Packit 98cdb6
  if (action & GDK_ACTION_COPY)
Packit 98cdb6
    result |= NSDragOperationCopy;
Packit 98cdb6
  if (action & GDK_ACTION_LINK)
Packit 98cdb6
    result |= NSDragOperationLink;
Packit 98cdb6
  if (action & GDK_ACTION_MOVE)
Packit 98cdb6
    result |= NSDragOperationMove;
Packit 98cdb6
Packit 98cdb6
  return result;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
update_context_from_dragging_info (id <NSDraggingInfo> sender)
Packit 98cdb6
{
Packit 98cdb6
  g_assert (current_context != NULL);
Packit 98cdb6
Packit 98cdb6
  GDK_DRAG_CONTEXT_PRIVATE (current_context)->dragging_info = sender;
Packit 98cdb6
  current_context->suggested_action = drag_operation_to_drag_action ([sender draggingSourceOperationMask]);
Packit 98cdb6
  current_context->actions = current_context->suggested_action;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
Packit 98cdb6
{
Packit 98cdb6
  GdkEvent event;
Packit 98cdb6
Packit 98cdb6
  if (current_context)
Packit 98cdb6
    g_object_unref (current_context);
Packit 98cdb6
  
Packit 98cdb6
  current_context = gdk_drag_context_new ();
Packit 98cdb6
  update_context_from_dragging_info (sender);
Packit 98cdb6
Packit 98cdb6
  event.dnd.type = GDK_DRAG_ENTER;
Packit 98cdb6
  event.dnd.window = g_object_ref ([[self contentView] gdkWindow]);
Packit 98cdb6
  event.dnd.send_event = FALSE;
Packit 98cdb6
  event.dnd.context = current_context;
Packit 98cdb6
  event.dnd.time = GDK_CURRENT_TIME;
Packit 98cdb6
Packit 98cdb6
  (*_gdk_event_func) (&event, _gdk_event_data);
Packit 98cdb6
Packit 98cdb6
  return NSDragOperationNone;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
- (void)draggingEnded:(id <NSDraggingInfo>)sender
Packit 98cdb6
{
Packit 98cdb6
  /* leave a note for the source about what action was taken */
Packit 98cdb6
  if (_gdk_quartz_drag_source_context && current_context)
Packit 98cdb6
   _gdk_quartz_drag_source_context->action = current_context->action;
Packit 98cdb6
Packit 98cdb6
  if (current_context)
Packit 98cdb6
    g_object_unref (current_context);
Packit 98cdb6
  current_context = NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
- (void)draggingExited:(id <NSDraggingInfo>)sender
Packit 98cdb6
{
Packit 98cdb6
  GdkEvent event;
Packit 98cdb6
  
Packit 98cdb6
  event.dnd.type = GDK_DRAG_LEAVE;
Packit 98cdb6
  event.dnd.window = g_object_ref ([[self contentView] gdkWindow]);
Packit 98cdb6
  event.dnd.send_event = FALSE;
Packit 98cdb6
  event.dnd.context = current_context;
Packit 98cdb6
  event.dnd.time = GDK_CURRENT_TIME;
Packit 98cdb6
Packit 98cdb6
  (*_gdk_event_func) (&event, _gdk_event_data);
Packit 98cdb6
  
Packit 98cdb6
  g_object_unref (current_context);
Packit 98cdb6
  current_context = NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
Packit 98cdb6
{
Packit 98cdb6
  NSPoint point = [sender draggingLocation];
Packit 98cdb6
  NSPoint screen_point = [self convertBaseToScreen:point];
Packit 98cdb6
  GdkEvent event;
Packit 98cdb6
  int gx, gy;
Packit 98cdb6
Packit 98cdb6
  update_context_from_dragging_info (sender);
Packit 98cdb6
  _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &gx, &gy;;
Packit 98cdb6
Packit 98cdb6
  event.dnd.type = GDK_DRAG_MOTION;
Packit 98cdb6
  event.dnd.window = g_object_ref ([[self contentView] gdkWindow]);
Packit 98cdb6
  event.dnd.send_event = FALSE;
Packit 98cdb6
  event.dnd.context = current_context;
Packit 98cdb6
  event.dnd.time = GDK_CURRENT_TIME;
Packit 98cdb6
  event.dnd.x_root = gx;
Packit 98cdb6
  event.dnd.y_root = gy;
Packit 98cdb6
Packit 98cdb6
  (*_gdk_event_func) (&event, _gdk_event_data);
Packit 98cdb6
Packit 98cdb6
  g_object_unref (event.dnd.window);
Packit 98cdb6
Packit 98cdb6
  return drag_action_to_drag_operation (current_context->action);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
Packit 98cdb6
{
Packit 98cdb6
  NSPoint point = [sender draggingLocation];
Packit 98cdb6
  NSPoint screen_point = [self convertBaseToScreen:point];
Packit 98cdb6
  GdkEvent event;
Packit 98cdb6
  int gy, gx;
Packit 98cdb6
Packit 98cdb6
  update_context_from_dragging_info (sender);
Packit 98cdb6
  _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &gx, &gy;;
Packit 98cdb6
Packit 98cdb6
  event.dnd.type = GDK_DROP_START;
Packit 98cdb6
  event.dnd.window = g_object_ref ([[self contentView] gdkWindow]);
Packit 98cdb6
  event.dnd.send_event = FALSE;
Packit 98cdb6
  event.dnd.context = current_context;
Packit 98cdb6
  event.dnd.time = GDK_CURRENT_TIME;
Packit 98cdb6
  event.dnd.x_root = gx;
Packit 98cdb6
  event.dnd.y_root = gy;
Packit 98cdb6
Packit 98cdb6
  (*_gdk_event_func) (&event, _gdk_event_data);
Packit 98cdb6
Packit 98cdb6
  g_object_unref (event.dnd.window);
Packit 98cdb6
Packit 98cdb6
  g_object_unref (current_context);
Packit 98cdb6
  current_context = NULL;
Packit 98cdb6
Packit 98cdb6
  return YES;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
- (BOOL)wantsPeriodicDraggingUpdates
Packit 98cdb6
{
Packit 98cdb6
  return NO;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
Packit 98cdb6
{
Packit 98cdb6
  GdkEvent event;
Packit 98cdb6
  GdkScreen *screen;
Packit 98cdb6
Packit 98cdb6
  g_assert (_gdk_quartz_drag_source_context != NULL);
Packit 98cdb6
Packit 98cdb6
  event.dnd.type = GDK_DROP_FINISHED;
Packit 98cdb6
  event.dnd.window = g_object_ref ([[self contentView] gdkWindow]);
Packit 98cdb6
  event.dnd.send_event = FALSE;
Packit 98cdb6
  event.dnd.context = _gdk_quartz_drag_source_context;
Packit 98cdb6
Packit 98cdb6
  screen = gdk_window_get_screen (event.dnd.window);
Packit 98cdb6
Packit 98cdb6
  if (screen)
Packit 98cdb6
    {
Packit 98cdb6
      GList* windows, *list;
Packit 98cdb6
      gint gx, gy;
Packit 98cdb6
Packit 98cdb6
      event.dnd.context->dest_window = NULL;
Packit 98cdb6
Packit 98cdb6
      windows = gdk_screen_get_toplevel_windows (screen);
Packit 98cdb6
      _gdk_quartz_window_nspoint_to_gdk_xy (aPoint, &gx, &gy;;
Packit 98cdb6
Packit 98cdb6
      for (list = windows; list; list = list->next) 
Packit 98cdb6
        {
Packit 98cdb6
          GdkWindow* win = (GdkWindow*) list->data;
Packit 98cdb6
          gint wx, wy;
Packit 98cdb6
          gint ww, wh;
Packit 98cdb6
Packit 98cdb6
          gdk_window_get_root_origin (win, &wx, &wy;;
Packit 98cdb6
          ww = gdk_window_get_width (win);
Packit 98cdb6
          wh = gdk_window_get_height (win);
Packit 98cdb6
Packit 98cdb6
          if (gx > wx && gy > wy && gx <= wx + ww && gy <= wy + wh)
Packit 98cdb6
            event.dnd.context->dest_window = win;
Packit 98cdb6
        }
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  (*_gdk_event_func) (&event, _gdk_event_data);
Packit 98cdb6
Packit 98cdb6
  g_object_unref (event.dnd.window);
Packit 98cdb6
Packit 98cdb6
  g_object_unref (_gdk_quartz_drag_source_context);
Packit 98cdb6
  _gdk_quartz_drag_source_context = NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
@end