Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  nsDragService.h   Sprache: C

 

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#ifndef nsDragService_h_
#define nsDragService_h_

#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "nsBaseDragService.h"
#include "nsCOMArray.h"
#include "nsIObserver.h"
#include <gtk/gtk.h>
#include "nsITimer.h"
#include "GUniquePtr.h"
#include "nsClipboard.h"

class nsICookieJarSettings;
class nsWindow;

namespace mozilla {
namespace gfx {
class SourceSurface;
}
}  // namespace mozilla

class DragData final {
 public:
  NS_INLINE_DECL_REFCOUNTING(DragData)

  explicit DragData(GdkAtom aDataFlavor, const void* aData, uint32_t aDataLen)
      : mDataFlavor(aDataFlavor),
        mDragDataLen(aDataLen),
        mDragData(moz_xmemdup(aData, aDataLen)) {
    // kURLMime (text/x-moz-url) is received as UTF16 raw data as
    // Gtk doesn't recognize it as URI format. We need to flip it to URI
    // format.
    if (IsURIFlavor()) {
      ConvertToMozURIList();
    }
  }
  explicit DragData(GdkAtom aDataFlavor, mozilla::GUniquePtr<char*> aDragUris);

  GdkAtom GetFlavor() const { return mDataFlavor; }

  // Try to convert text/uri-list or _NETSCAPE_URL MIME to x-moz-url MIME type
  // which is used internally.
  RefPtr<DragData> ConvertToMozURL() const;

  // Try to convert text/uri-list MIME to application/x-moz-file MIME type.
  RefPtr<DragData> ConvertToFile() const;

  bool Export(nsITransferable* aTransferable, uint32_t aItemIndex);

  bool IsImageFlavor() const;
  bool IsFileFlavor() const;
  bool IsTextFlavor() const;
  bool IsURIFlavor() const;

  int GetURIsNum() const;

  bool IsDataValid() const;

#ifdef MOZ_LOGGING
  void Print() const;
#endif

 private:
  explicit DragData(GdkAtom aDataFlavor) : mDataFlavor(aDataFlavor) {}
  ~DragData() = default;

  void ConvertToMozURIList();

  GdkAtom mDataFlavor = nullptr;

  bool mAsURIData = false;

  // In a rare case we export
  bool mDragDataDOMEndings = false;

  // Data obtained from Gtk
  uint32_t mDragDataLen = 0;
  mozilla::UniqueFreePtr<void> mDragData;
  mozilla::GUniquePtr<gchar*> mDragUris;

  // Data which can be passed to transferable. In some cases we can use Gtk data
  // directly but in most cases we need to do UTF8/UTF16 conversion
  // and perform line break;
  nsString mData;
  nsTArray<nsString> mUris;
};

/**
 * GTK native nsIDragSession implementation
 */

class nsDragSession : public nsBaseDragSession, public nsIObserver {
 public:
  NS_DECL_ISUPPORTS_INHERITED
  NS_DECL_NSIOBSERVER

  // nsIDragSession
  NS_IMETHOD SetCanDrop(bool aCanDrop) override;
  NS_IMETHOD GetCanDrop(bool* aCanDrop) override;

  // Spins event loop, called from JS.
  // Can lead to another round of drag_motion events.
  NS_IMETHOD GetNumDropItems(uint32_t* aNumItems) override;
  NS_IMETHOD GetData(nsITransferable* aTransferable,
                     uint32_t aItemIndex) override;
  NS_IMETHOD IsDataFlavorSupported(const char* aDataFlavor,
                                   bool* _retval) override;

  nsAutoCString GetDebugTag() const;

  MOZ_CAN_RUN_SCRIPT nsresult
  EndDragSessionImpl(bool aDoneDrag, uint32_t aKeyModifiers) override;
  MOZ_CAN_RUN_SCRIPT void EndDragSessionMainThread();

  class AutoEventLoop {
    RefPtr<nsDragSession> mSession;

   public:
    explicit AutoEventLoop(RefPtr<nsDragSession> aSession)
        : mSession(std::move(aSession)) {
      nsDragSession::sEventLoopDepth++;
    }
    ~AutoEventLoop() { nsDragSession::sEventLoopDepth--; }
  };

  static int GetLoopDepth() { return sEventLoopDepth; };

  static bool IsTextFlavor(GdkAtom aFlavor);

  virtual void ScheduleLeaveEvent() = 0;

 protected:
  // mScheduledTask indicates what signal has been received from GTK and
  // so what needs to be dispatched when the scheduled task is run.  It is
  // eDragTaskNone when there is no task scheduled (but the
  // previous task may still not have finished running).
  enum DragTaskType {
    eDragTaskNone,
    eDragTaskMotion,
    eDragTaskLeave,
    eDragTaskDrop
  };

  struct DragTask {
    DragTask(DragTaskType aType = eDragTaskNone, nsWindow* aWindow = nullptr,
             const mozilla::LayoutDeviceIntPoint& aWindowPoint =
                 mozilla::LayoutDeviceIntPoint(),
             guint aTime = 0);
    virtual ~DragTask() = default;

    virtual void Reset() = 0;
    virtual uintptr_t GetContextID() = 0;

    DragTaskType mType;
    RefPtr<nsWindow> mWindow;
    mozilla::LayoutDeviceIntPoint mWindowPoint;
    guint mTime;
  };
  // Next drag task in queue
  mozilla::UniquePtr<DragTask> mNextScheduledTask;
  bool mScheduledTaskIsRunning = false;

  // Recent drag task, always present.
  // If empty it's mType = eDragTaskNone.
  mozilla::UniquePtr<DragTask> mRecentTask;

  gboolean Schedule(mozilla::UniquePtr<DragTask> aTask);

  void GetDragFlavors(nsTArray<nsCString>& aFlavors);
  // this will get the native data from the last target given a
  // specific flavor
  void GetTargetDragData(GdkAtom aFlavor, nsTArray<nsCString>& aDropFlavors,
                         bool aResetTargetData = true);
  // this will reset all of the target vars
  void TargetResetData(void);

  virtual void SetRemoteContext() = 0;

  virtual void DropFinish(bool aSucceed) = 0;

  // X11/Wayland specific EndDragSessionImpl handler.
  virtual void EndDragSessionImplBackend() = 0;

  // is the current target drag context contain a list?
  virtual bool IsTargetContextList(void) = 0;

  static gboolean TaskRemoveTempFiles(gpointer data);

  bool RemoveTempFiles();

  // We can't overload SetDragAction()/GetDragAction() with
  // the same type of param (int) so use Gtk() suffix.
  void SetDragActionGtk(GdkDragAction aGdkAction);
  GdkDragAction GetDragActionGtk();

#ifdef MOZ_LOGGING
  const char* GetDragServiceTaskName(DragTaskType aTask);
#endif

  MOZ_CAN_RUN_SCRIPT gboolean RunScheduledTask();
  static MOZ_CAN_RUN_SCRIPT int RunScheduledTaskCallback(void* aData);
  MOZ_CAN_RUN_SCRIPT void RunScheduledTask(mozilla::UniquePtr<DragTask> aTask);
  MOZ_CAN_RUN_SCRIPT void DispatchMotionEvents();
  void DispatchDropEvent();
  static uint32_t GetCurrentModifiers();

  void SetCachedDragContext(uintptr_t aDragContextID);

  virtual void ReplyToDragMotion() = 0;
  virtual void UpdateDragAction() = 0;

  bool mDragTaskSourceFinished = false;

  // Where the drag begins. We need to keep it open on Wayland.
  RefPtr<nsWindow> mSourceWindow;

  // our source data items
  nsCOMPtr<nsIArray> mSourceDataItems;

  // last data received and its length
  void* mTargetDragData = nullptr;
  uint32_t mTargetDragDataLen = 0;

  // have we received our drag data?
  bool mTargetDragDataReceived = false;

  mozilla::GUniquePtr<gchar*> mTargetDragUris = nullptr;

  nsTHashMap<nsCStringHashKey, mozilla::GUniquePtr<gchar*>> mCachedUris;

  // We cache all data for the current drag context,
  // because waiting for the data in GetTargetDragData can be very slow.
  nsTHashMap<nsCStringHashKey, nsTArray<uint8_t>> mCachedData;

  // mTaskSource is the GSource id for the task that is either scheduled
  // or currently running.  It is 0 if no task is scheduled or running.
  guint mTaskSource = 0;

  // stores all temporary files
  nsCOMArray<nsIFile> mTemporaryFiles;
  // timer to trigger deletion of temporary files
  guint mTempFileTimerID;
  // the url of the temporary file that has been created in the current drag
  // session
  nsTArray<nsCString> mTempFileUrls;

  // How deep we're nested in event loops
  static int sEventLoopDepth;

  // is it OK to drop on us?
  bool mCanDrop = false;

 public:
  static GdkAtom sJPEGImageMimeAtom;
  static GdkAtom sJPGImageMimeAtom;
  static GdkAtom sPNGImageMimeAtom;
  static GdkAtom sGIFImageMimeAtom;
  static GdkAtom sCustomTypesMimeAtom;
  static GdkAtom sURLMimeAtom;
  static GdkAtom sRTFMimeAtom;
  static GdkAtom sTextMimeAtom;
  static GdkAtom sMozUrlTypeAtom;
  static GdkAtom sMimeListTypeAtom;
  static GdkAtom sTextUriListTypeAtom;
  static GdkAtom sTextPlainUTF8TypeAtom;
  static GdkAtom sXdndDirectSaveTypeAtom;
  static GdkAtom sTabDropTypeAtom;
  static GdkAtom sFileMimeAtom;
  static GdkAtom sPortalFileAtom;
  static GdkAtom sPortalFileTransferAtom;
  static GdkAtom sFilePromiseURLMimeAtom;
  static GdkAtom sFilePromiseMimeAtom;
  static GdkAtom sNativeImageMimeAtom;
  static GdkAtom sUTF8STRINGMimeAtom;
  static GdkAtom sSTRINGMimeAtom;

  nsDragSession();

  // nsBaseDragSession
  MOZ_CAN_RUN_SCRIPT virtual nsresult InvokeDragSessionImpl(
      nsIWidget* aWidget, nsIArray* anArrayTransferables,
      const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
      uint32_t aActionType) override;

  // nsIDragSession
  MOZ_CAN_RUN_SCRIPT NS_IMETHOD InvokeDragSession(
      nsIWidget* aWidget, nsINode* aDOMNode, nsIPrincipal* aPrincipal,
      nsIPolicyContainer* aPolicyContainer,
      nsICookieJarSettings* aCookieJarSettings, nsIArray* anArrayTransferables,
      uint32_t aActionType, nsContentPolicyType aContentPolicyType) override;

  // Methods called from nsWindow to handle responding to GTK drag
  // destination signals
  virtual nsWindow* GetMostRecentDestWindow() = 0;

  //  END PUBLIC API

  // These methods are public only so that they can be called from functions
  // with C calling conventions.  They are called for drags started with the
  // invisible widget.
  void SourceEndDragSession(GdkDragContext* aContext, gint aResult);
  void SourceDataGet(GtkWidget* widget, GdkDragContext* context,
                     GtkSelectionData* selection_data, guint32 aTime);
  bool SourceDataGetText(nsITransferable* aItem, const nsACString& aMIMEType,
                         bool aNeedToDoConversionToPlainText,
                         GtkSelectionData* aSelectionData);
  bool SourceDataGetImage(nsITransferable* aItem,
                          GtkSelectionData* aSelectionData);
  bool SourceDataGetXDND(nsITransferable* aItem, GdkDragContext* aContext,
                         GtkSelectionData* aSelectionData);
  void SourceDataGetUriList(GdkDragContext* aContext,
                            GtkSelectionData* aSelectionData,
                            uint32_t aDragItems);
  bool SourceDataAppendURLFileItem(nsACString& aURI, nsITransferable* aItem);
  bool SourceDataAppendURLItem(nsITransferable* aItem, bool aExternalDrop,
                               nsACString& aURI);
  void SourceBeginDrag(GdkDragContext* aContext);

  // set the drag icon during drag-begin
  void SetDragIcon(GdkDragContext* aContext);

  void MarkAsActive() { mActive = true; }
  bool IsActive() const { return mActive; }

 protected:
  virtual ~nsDragSession();

  // target/destination side vars
  // These variables keep track of the state of the current drag.

  // mCachedDragData/mCachedDragFlavors are tied to mCachedDragContextID.
  // mCachedDragContextID is not ref counted and may be already deleted
  // on Gtk side.
  // We used it for mCachedDragData/mCachedDragFlavors invalidation
  // only and can't be used for any D&D operation.
  uintptr_t mCachedDragContextID = 0;
  nsTHashMap<void*, RefPtr<DragData>> mCachedDragData;
  mozilla::ClipboardTargets mCachedDragFlavors;

  virtual bool IsDragFlavorAvailable(GdkAtom aRequestedFlavor) = 0;

  // this will get the native data from the last target given a
  // specific flavor
  RefPtr<DragData> GetDragData(GdkAtom aRequestedFlavor);
  virtual bool GetDragDataImpl(GdkAtom aRequestedFlavor) = 0;

  // attempts to create a semi-transparent drag image. Returns TRUE if
  // successful, FALSE if not
  bool SetAlphaPixmap(mozilla::gfx::SourceSurface* aPixbuf,
                      GdkDragContext* aContext, int32_t aXOffset,
                      int32_t aYOffset,
                      const mozilla::LayoutDeviceIntRect& dragRect);

  // source side vars

  // the source of our drags
  GtkWidget* mHiddenWidget;
  // Workaround for Bug 1979719. We consider D&D session running only after
  // first "move" event on Wayland.
  bool mActive = false;

  // get a list of the sources in gtk's format
  GtkTargetList* GetSourceList(void);

  nsresult CreateTempFile(nsITransferable* aItem, nsACString& aURI);
};

/**
 * Native GTK nsIDragService implementation
 */

class nsDragService : public nsBaseDragService {
 public:
  nsDragService();

  static already_AddRefed<nsDragService> GetInstance();
  nsIDragSession* StartDragSession(nsISupports* aWidgetProvider) override;

 protected:
  already_AddRefed<nsIDragSession> CreateDragSession() override;
#ifdef MOZ_WAYLAND
  RefPtr<mozilla::RetrievalContext> mContext;
#endif
};

#endif  // nsDragService_h_

Messung V0.5 in Prozent
C=82 H=100 G=91

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet am  2026-09-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1126438
#Domains=1897691