Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / vcl / inc / unx / gtk / gtkframe.hxx
blob1f28dd0804bfd998e1da5b50d7079e6f9e60b524
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_VCL_INC_UNX_GTK_GTKFRAME_HXX
21 #define INCLUDED_VCL_INC_UNX_GTK_GTKFRAME_HXX
23 #include <cairo.h>
24 #include <gdk/gdk.h>
25 #include <gdk/gdkx.h>
26 #include <gtk/gtk.h>
27 #if GTK_CHECK_VERSION(3,0,0)
28 # include <gtk/gtkx.h>
29 #endif
30 #include <gdk/gdkkeysyms.h>
32 #include <salframe.hxx>
33 #include <vcl/idle.hxx>
34 #include <vcl/sysdata.hxx>
35 #include <unx/nativewindowhandleprovider.hxx>
36 #include <unx/saltype.h>
37 #include <unx/screensaverinhibitor.hxx>
39 #include "tools/link.hxx"
41 #include <com/sun/star/awt/XTopWindow.hpp>
42 #include <com/sun/star/datatransfer/DataFlavor.hpp>
43 #include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
44 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
46 #include <list>
47 #include <vector>
49 #include <config_dbus.h>
50 #include <config_gio.h>
52 #include "headless/svpgdi.hxx"
54 class GtkSalGraphics;
55 class GtkSalDisplay;
57 #if GTK_CHECK_VERSION(3,0,0)
58 typedef ::Window GdkNativeWindow;
59 #define GDK_WINDOW_XWINDOW(o) GDK_WINDOW_XID(o)
60 #define gdk_set_sm_client_id(i) gdk_x11_set_sm_client_id(i)
61 #define gdk_window_foreign_new_for_display(a,b) gdk_x11_window_foreign_new_for_display(a,b)
62 class GtkDropTarget;
63 class GtkDragSource;
64 class GtkDnDTransferable;
65 #endif
67 #if !(GLIB_MAJOR_VERSION > 2 || GLIB_MINOR_VERSION >= 26)
68 typedef void GDBusConnection;
69 #endif
71 class GtkSalFrame : public SalFrame
72 , public NativeWindowHandleProvider
74 struct IMHandler
77 // Not all GTK Input Methods swallow key release
78 // events. Since they swallow the key press events and we
79 // are left with the key release events, we need to
80 // manually swallow those. To do this, we keep a list of
81 // the previous 10 key press events in each GtkSalFrame
82 // and when we get a key release that matches one of the
83 // key press events in our list, we swallow it.
84 struct PreviousKeyPress
86 GdkWindow *window;
87 gint8 send_event;
88 guint32 time;
89 guint state;
90 guint keyval;
91 guint16 hardware_keycode;
92 guint8 group;
94 PreviousKeyPress (GdkEventKey *event)
95 : window (nullptr),
96 send_event (0),
97 time (0),
98 state (0),
99 keyval (0),
100 hardware_keycode (0),
101 group (0)
103 if (event)
105 window = event->window;
106 send_event = event->send_event;
107 time = event->time;
108 state = event->state;
109 keyval = event->keyval;
110 hardware_keycode = event->hardware_keycode;
111 group = event->group;
115 PreviousKeyPress( const PreviousKeyPress& rPrev )
116 : window( rPrev.window ),
117 send_event( rPrev.send_event ),
118 time( rPrev.time ),
119 state( rPrev.state ),
120 keyval( rPrev.keyval ),
121 hardware_keycode( rPrev.hardware_keycode ),
122 group( rPrev.group )
125 bool operator== (GdkEventKey *event) const
127 return (event != nullptr)
128 && (event->window == window)
129 && (event->send_event == send_event)
130 // ignore non-Gdk state bits, e.g., these used by IBus
131 && ((event->state & GDK_MODIFIER_MASK) == (state & GDK_MODIFIER_MASK))
132 && (event->keyval == keyval)
133 && (event->hardware_keycode == hardware_keycode)
134 && (event->group == group)
135 && (event->time - time < 300)
140 GtkSalFrame* m_pFrame;
141 std::list< PreviousKeyPress > m_aPrevKeyPresses;
142 int m_nPrevKeyPresses; // avoid using size()
143 GtkIMContext* m_pIMContext;
144 bool m_bFocused;
145 bool m_bPreeditJustChanged;
146 SalExtTextInputEvent m_aInputEvent;
147 std::vector< ExtTextInputAttr > m_aInputFlags;
149 IMHandler( GtkSalFrame* );
150 ~IMHandler();
152 void createIMContext();
153 void deleteIMContext();
154 void updateIMSpotLocation();
155 void endExtTextInput( EndExtTextInputFlags nFlags );
156 bool handleKeyEvent( GdkEventKey* pEvent );
157 void focusChanged( bool bFocusIn );
159 void doCallEndExtTextInput();
160 void sendEmptyCommit();
162 static void signalIMCommit( GtkIMContext*, gchar*, gpointer );
163 static gboolean signalIMDeleteSurrounding( GtkIMContext*, gint, gint, gpointer );
164 static void signalIMPreeditChanged( GtkIMContext*, gpointer );
165 static void signalIMPreeditEnd( GtkIMContext*, gpointer );
166 static void signalIMPreeditStart( GtkIMContext*, gpointer );
167 static gboolean signalIMRetrieveSurrounding( GtkIMContext*, gpointer );
169 friend struct IMHandler;
171 SalX11Screen m_nXScreen;
172 GtkWidget* m_pWindow;
173 #if GTK_CHECK_VERSION(3,0,0)
174 GtkGrid* m_pTopLevelGrid;
175 #endif
176 GtkEventBox* m_pEventBox;
177 GtkFixed* m_pFixedContainer;
178 GdkWindow* m_pForeignParent;
179 GdkNativeWindow m_aForeignParentWindow;
180 GdkWindow* m_pForeignTopLevel;
181 GdkNativeWindow m_aForeignTopLevelWindow;
182 SalFrameStyleFlags m_nStyle;
183 GtkSalFrame* m_pParent;
184 std::list< GtkSalFrame* > m_aChildren;
185 GdkWindowState m_nState;
186 SystemEnvData m_aSystemData;
187 GtkSalGraphics *m_pGraphics;
188 bool m_bGraphics;
189 ModKeyFlags m_nKeyModifiers;
190 GdkCursor *m_pCurrentCursor;
191 GdkVisibilityState m_nVisibility;
192 PointerStyle m_ePointerStyle;
193 ScreenSaverInhibitor m_ScreenSaverInhibitor;
194 int m_nWorkArea;
195 bool m_bFullscreen;
196 bool m_bSpanMonitorsWhenFullscreen;
197 bool m_bDefaultPos;
198 bool m_bDefaultSize;
199 bool m_bWindowIsGtkPlug;
200 OUString m_aTitle;
201 OUString m_sWMClass;
203 IMHandler* m_pIMHandler;
205 Size m_aMaxSize;
206 Size m_aMinSize;
207 tools::Rectangle m_aRestorePosSize;
209 #if GTK_CHECK_VERSION(3,0,0)
210 OUString m_aTooltip;
211 tools::Rectangle m_aHelpArea;
212 long m_nWidthRequest;
213 long m_nHeightRequest;
214 cairo_region_t* m_pRegion;
215 GtkDropTarget* m_pDropTarget;
216 GtkDragSource* m_pDragSource;
217 bool m_bInDrag;
218 GtkDnDTransferable* m_pFormatConversionRequest;
219 #else
220 GdkRegion* m_pRegion;
221 bool m_bSetFocusOnMap;
222 #endif
224 SalMenu* m_pSalMenu;
226 #if ENABLE_DBUS && ENABLE_GIO
227 private:
228 friend void ensure_dbus_setup(GdkWindow* gdkWindow, GtkSalFrame* pSalFrame);
229 friend void on_registrar_available (GDBusConnection*, const gchar*, const gchar*, gpointer);
230 friend void on_registrar_unavailable (GDBusConnection*, const gchar*, gpointer);
231 #endif
232 guint m_nWatcherId;
234 void Init( SalFrame* pParent, SalFrameStyleFlags nStyle );
235 void Init( SystemParentData* pSysData );
236 void InitCommon();
237 void InvalidateGraphics();
239 // signals
240 static gboolean signalButton( GtkWidget*, GdkEventButton*, gpointer );
241 #if GTK_CHECK_VERSION(3,0,0)
242 static void signalStyleUpdated(GtkWidget*, gpointer);
243 #else
244 static void signalStyleSet(GtkWidget*, GtkStyle* pPrevious, gpointer);
245 #endif
246 #if GTK_CHECK_VERSION(3,0,0)
247 static gboolean signalDraw( GtkWidget*, cairo_t *cr, gpointer );
248 static void signalRealize(GtkWidget*, gpointer frame);
249 static void sizeAllocated(GtkWidget*, GdkRectangle *pAllocation, gpointer frame);
250 static gboolean signalTooltipQuery(GtkWidget*, gint x, gint y,
251 gboolean keyboard_mode, GtkTooltip *tooltip,
252 gpointer frame);
253 static gboolean signalDragMotion(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
254 guint time, gpointer frame);
255 static gboolean signalDragDrop(GtkWidget* widget, GdkDragContext *context, gint x, gint y,
256 guint time, gpointer frame);
257 static void signalDragDropReceived(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
258 GtkSelectionData *data, guint ttype, guint time, gpointer frame);
259 static void signalDragLeave(GtkWidget *widget, GdkDragContext *context, guint time, gpointer frame);
261 static gboolean signalDragFailed(GtkWidget *widget, GdkDragContext *context, GtkDragResult result, gpointer frame);
262 static void signalDragDelete(GtkWidget *widget, GdkDragContext *context, gpointer frame);
263 static void signalDragEnd(GtkWidget *widget, GdkDragContext *context, gpointer frame);
264 static void signalDragDataGet(GtkWidget* widget, GdkDragContext* context, GtkSelectionData *data, guint info,
265 guint time, gpointer frame);
267 #if GTK_CHECK_VERSION(3,14,0)
268 static void gestureSwipe(GtkGestureSwipe* gesture, gdouble velocity_x, gdouble velocity_y, gpointer frame);
269 static void gestureLongPress(GtkGestureLongPress* gesture, gpointer frame);
270 #endif
271 #else
272 static gboolean signalExpose( GtkWidget*, GdkEventExpose*, gpointer );
273 void askForXEmbedFocus( sal_Int32 nTimecode );
274 void grabKeyboard(bool bGrab);
275 #endif
276 static gboolean signalFocus( GtkWidget*, GdkEventFocus*, gpointer );
277 static gboolean signalMap( GtkWidget*, GdkEvent*, gpointer );
278 static gboolean signalUnmap( GtkWidget*, GdkEvent*, gpointer );
279 static gboolean signalConfigure( GtkWidget*, GdkEventConfigure*, gpointer );
280 static gboolean signalMotion( GtkWidget*, GdkEventMotion*, gpointer );
281 static gboolean signalKey( GtkWidget*, GdkEventKey*, gpointer );
282 static gboolean signalDelete( GtkWidget*, GdkEvent*, gpointer );
283 static gboolean signalWindowState( GtkWidget*, GdkEvent*, gpointer );
284 static gboolean signalScroll( GtkWidget*, GdkEvent*, gpointer );
285 static gboolean signalCrossing( GtkWidget*, GdkEventCrossing*, gpointer );
286 static gboolean signalVisibility( GtkWidget*, GdkEventVisibility*, gpointer );
287 static void signalDestroy( GtkWidget*, gpointer );
289 void Center();
290 void SetDefaultSize();
292 bool doKeyCallback( guint state,
293 guint keyval,
294 guint16 hardware_keycode,
295 guint8 group,
296 guint32 time,
297 sal_Unicode aOrigCode,
298 bool bDown,
299 bool bSendRelease
302 static GdkNativeWindow findTopLevelSystemWindow( GdkNativeWindow aWindow );
304 static int m_nFloats;
306 bool isFloatGrabWindow() const
308 return
309 (m_nStyle & SalFrameStyleFlags::FLOAT) && // only a float can be floatgrab
310 !(m_nStyle & SalFrameStyleFlags::TOOLTIP) && // tool tips are not
311 !(m_nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION); // toolbars are also not
314 bool isChild( bool bPlug = true, bool bSysChild = true )
316 SalFrameStyleFlags nMask = SalFrameStyleFlags::NONE;
317 if( bPlug )
318 nMask |= SalFrameStyleFlags::PLUG;
319 if( bSysChild )
320 nMask |= SalFrameStyleFlags::SYSTEMCHILD;
321 return bool(m_nStyle & nMask);
324 //call gtk_window_resize
325 void window_resize(long nWidth, long nHeight);
326 //call gtk_widget_set_size_request
327 void widget_set_size_request(long nWidth, long nHeight);
329 void resizeWindow( long nWidth, long nHeight );
330 void moveWindow( long nX, long nY );
332 Size calcDefaultSize();
334 void setMinMaxSize();
335 void createNewWindow( ::Window aParent, bool bXEmbed, SalX11Screen nXScreen );
337 void AllocateFrame();
338 void TriggerPaintEvent();
340 void updateWMClass();
342 enum class SetType { RetainSize, Fullscreen, UnFullscreen };
344 void SetScreen( unsigned int nNewScreen, SetType eType, tools::Rectangle *pSize = nullptr );
346 public:
347 #if GTK_CHECK_VERSION(3,0,0)
348 cairo_surface_t* m_pSurface;
349 basegfx::B2IVector m_aFrameSize;
350 DamageHandler m_aDamageHandler;
351 std::vector<GdkEvent*> m_aPendingScrollEvents;
352 Idle m_aSmoothScrollIdle;
353 int m_nGrabLevel;
354 bool m_bSalObjectSetPosSize;
355 #endif
356 GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle );
357 GtkSalFrame( SystemParentData* pSysData );
359 guint m_nMenuExportId;
360 guint m_nAppMenuExportId;
361 guint m_nActionGroupExportId;
362 guint m_nAppActionGroupExportId;
363 guint m_nHudAwarenessId;
364 std::vector<gulong> m_aMouseSignalIds;
366 // dispatches an event, returns true if dispatched
367 // and false else; if true was returned the event should
368 // be swallowed
369 bool Dispatch( const XEvent* pEvent );
370 void grabPointer(bool bGrab, bool bOwnerEvents = false);
372 static GtkSalDisplay* getDisplay();
373 static GdkDisplay* getGdkDisplay();
374 GtkWidget* getWindow() const { return m_pWindow; }
375 GtkFixed* getFixedContainer() const { return m_pFixedContainer; }
376 GtkEventBox* getEventBox() const { return m_pEventBox; }
377 GtkWidget* getMouseEventWidget() const;
378 #if GTK_CHECK_VERSION(3,0,0)
379 GtkGrid* getTopLevelGridWidget() const { return m_pTopLevelGrid; }
380 #endif
381 GdkWindow* getForeignParent() const { return m_pForeignParent; }
382 GdkNativeWindow getForeignParentWindow() const { return m_aForeignParentWindow; }
383 GdkWindow* getForeignTopLevel() const { return m_pForeignTopLevel; }
384 GdkNativeWindow getForeignTopLevelWindow() const { return m_aForeignTopLevelWindow; }
385 const SalX11Screen& getXScreenNumber() const { return m_nXScreen; }
386 int GetDisplayScreen() const { return maGeometry.nDisplayScreenNumber; }
387 void updateScreenNumber();
389 #if GTK_CHECK_VERSION(3,0,0)
390 // only for gtk3 ...
391 cairo_t* getCairoContext() const;
392 void damaged(sal_Int32 nExtentsLeft, sal_Int32 nExtentsTop,
393 sal_Int32 nExtentsRight, sal_Int32 nExtentsBottom) const;
395 void registerDropTarget(GtkDropTarget* pDropTarget)
397 assert(!m_pDropTarget);
398 m_pDropTarget = pDropTarget;
401 void deregisterDropTarget(GtkDropTarget* pDropTarget)
403 assert(m_pDropTarget == pDropTarget); (void)pDropTarget;
404 m_pDropTarget = nullptr;
407 void registerDragSource(GtkDragSource* pDragSource)
409 assert(!m_pDragSource);
410 m_pDragSource = pDragSource;
413 void deregisterDragSource(GtkDragSource* pDragSource)
415 assert(m_pDragSource == pDragSource); (void)pDragSource;
416 m_pDragSource = nullptr;
419 void SetFormatConversionRequest(GtkDnDTransferable *pRequest)
421 m_pFormatConversionRequest = pRequest;
424 void startDrag(gint nButton, gint nDragOriginX, gint nDragOriginY,
425 GdkDragAction sourceActions, GtkTargetList* pTargetList);
427 void closePopup();
429 void addGrabLevel();
430 void removeGrabLevel();
432 void nopaint_container_resize_children(GtkContainer*);
434 void LaunchAsyncScroll(GdkEvent* pEvent);
435 DECL_LINK(AsyncScroll, Timer *, void);
437 #endif
438 virtual ~GtkSalFrame() override;
440 // SalGraphics or NULL, but two Graphics for all SalFrames
441 // must be returned
442 virtual SalGraphics* AcquireGraphics() override;
443 virtual void ReleaseGraphics( SalGraphics* pGraphics ) override;
445 // Event must be destroyed, when Frame is destroyed
446 // When Event is called, SalInstance::Yield() must be returned
447 virtual bool PostEvent(ImplSVEvent* pData) override;
449 virtual void SetTitle( const OUString& rTitle ) override;
450 virtual void SetIcon( sal_uInt16 nIcon ) override;
451 virtual void SetMenu( SalMenu *pSalMenu ) override;
452 SalMenu* GetMenu();
453 virtual void DrawMenuBar() override;
454 void EnsureAppMenuWatch();
456 virtual void SetExtendedFrameStyle( SalExtStyle nExtStyle ) override;
457 // Before the window is visible, a resize event
458 // must be sent with the correct size
459 virtual void Show( bool bVisible, bool bNoActivate = false ) override;
460 // Set ClientSize and Center the Window to the desktop
461 // and send/post a resize message
462 virtual void SetMinClientSize( long nWidth, long nHeight ) override;
463 virtual void SetMaxClientSize( long nWidth, long nHeight ) override;
464 virtual void SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags ) override;
465 virtual void GetClientSize( long& rWidth, long& rHeight ) override;
466 virtual void GetWorkArea( tools::Rectangle& rRect ) override;
467 virtual SalFrame* GetParent() const override;
468 virtual void SetWindowState( const SalFrameState* pState ) override;
469 virtual bool GetWindowState( SalFrameState* pState ) override;
470 virtual void ShowFullScreen( bool bFullScreen, sal_Int32 nDisplay ) override;
471 // Enable/Disable ScreenSaver, SystemAgents, ...
472 virtual void StartPresentation( bool bStart ) override;
473 // Show Window over all other Windows
474 virtual void SetAlwaysOnTop( bool bOnTop ) override;
476 // Window to top and grab focus
477 virtual void ToTop( SalFrameToTop nFlags ) override;
479 // this function can call with the same
480 // pointer style
481 virtual void SetPointer( PointerStyle ePointerStyle ) override;
482 virtual void CaptureMouse( bool bMouse ) override;
483 virtual void SetPointerPos( long nX, long nY ) override;
485 // flush output buffer
486 using SalFrame::Flush;
487 virtual void Flush() override;
488 // flush output buffer, wait till outstanding operations are done
490 virtual void SetInputContext( SalInputContext* pContext ) override;
491 virtual void EndExtTextInput( EndExtTextInputFlags nFlags ) override;
493 virtual OUString GetKeyName( sal_uInt16 nKeyCode ) override;
494 virtual bool MapUnicodeToKeyCode( sal_Unicode aUnicode, LanguageType aLangType, vcl::KeyCode& rKeyCode ) override;
496 // returns the input language used for the last key stroke
497 // may be LANGUAGE_DONTKNOW if not supported by the OS
498 virtual LanguageType GetInputLanguage() override;
500 virtual void UpdateSettings( AllSettings& rSettings ) override;
502 virtual void Beep() override;
504 // returns system data (most prominent: window handle)
505 virtual const SystemEnvData* GetSystemData() const override;
507 // get current modifier and button mask
508 virtual SalPointerState GetPointerState() override;
510 virtual KeyIndicatorState GetIndicatorState() override;
512 virtual void SimulateKeyPress( sal_uInt16 nKeyCode ) override;
514 // set new parent window
515 virtual void SetParent( SalFrame* pNewParent ) override;
516 // reparent window to act as a plugin; implementation
517 // may choose to use a new system window internally
518 // return false to indicate failure
519 virtual bool SetPluginParent( SystemParentData* pNewParent ) override;
521 virtual void SetScreenNumber( unsigned int ) override;
522 virtual void SetApplicationID( const OUString &rWMClass ) override;
524 // shaped system windows
525 // set clip region to none (-> rectangular windows, normal state)
526 virtual void ResetClipRegion() override;
527 // start setting the clipregion consisting of nRects rectangles
528 virtual void BeginSetClipRegion( sal_uLong nRects ) override;
529 // add a rectangle to the clip region
530 virtual void UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) override;
531 // done setting up the clipregion
532 virtual void EndSetClipRegion() override;
534 #if GTK_CHECK_VERSION(3,0,0)
535 virtual void SetModal(bool bModal) override;
536 virtual bool ShowTooltip(const OUString& rHelpText, const tools::Rectangle& rHelpArea) override;
537 virtual sal_uIntPtr ShowPopover(const OUString& rHelpText, const tools::Rectangle& rHelpArea, QuickHelpFlags nFlags) override;
538 virtual bool UpdatePopover(sal_uIntPtr nId, const OUString& rHelpText, const tools::Rectangle& rHelpArea) override;
539 virtual bool HidePopover(sal_uIntPtr nId) override;
540 #endif
542 static GtkSalFrame *getFromWindow( GtkWindow *pWindow );
544 sal_uIntPtr GetNativeWindowHandle(GtkWidget *pWidget);
545 virtual sal_uIntPtr GetNativeWindowHandle() override;
547 //Call the usual SalFrame Callback, but catch uno exceptions and delegate
548 //to GtkData to rethrow them after the gsignal is processed when its safe
549 //to do so again in our own code after the g_main_context_iteration call
550 //which triggers the gsignals.
551 long CallCallbackExc(SalEvent nEvent, const void* pEvent) const;
554 static void KeyCodeToGdkKey(const vcl::KeyCode& rKeyCode,
555 guint* pGdkKeyCode, GdkModifierType *pGdkModifiers);
557 static guint32 GetLastInputEventTime();
558 static void UpdateLastInputEventTime(guint32 nUserInputTime);
561 #define OOO_TYPE_FIXED ooo_fixed_get_type()
563 extern "C" {
565 GType ooo_fixed_get_type();
566 AtkObject* ooo_fixed_get_accessible(GtkWidget *obj);
568 } // extern "C"
570 #endif // INCLUDED_VCL_INC_UNX_GTK_GTKFRAME_HXX
572 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */