Mercurial > projects > dwt-linux
diff dwt/browser/MozillaDelegate.d @ 278:93409d9838c5
Commit more browser/xpcom updates, including still uncoverted source.
author | John Reimer<terminal.node@gmail.com> |
---|---|
date | Thu, 31 Jul 2008 19:17:51 -0700 |
parents | |
children | 44258e0b6687 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/browser/MozillaDelegate.d Thu Jul 31 19:17:51 2008 -0700 @@ -0,0 +1,208 @@ +/******************************************************************************* + * Copyright (c) 2003, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +module dwt.browser.MozillaDelegate; + +import dwt.dwthelper.utils; + +import dwt.DWT; +import dwt.internal.Callback; +import dwt.internal.Converter; +import dwt.internal.gtk.GdkEvent; +import dwt.internal.gtk.OS; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwt.widgets.Widget; + +class MozillaDelegate { + Browser browser; + int /*long*/ mozillaHandle, embedHandle; + bool hasFocus; + Listener listener; + static Callback eventCallback; + static int /*long*/ eventProc; + static final int STOP_PROPOGATE = 1; + + static bool IsLinux; + static { + String osName = System.getProperty ("os.name").toLowerCase (); //$NON-NLS-1$ + IsLinux = osName.startsWith ("linux"); //$NON-NLS-1$ + } + +MozillaDelegate (Browser browser) { + super (); + if (!IsLinux) { + browser.dispose (); + DWT.error (DWT.ERROR_NO_HANDLES, null, " [Unsupported platform]"); //$NON-NLS-1$ + } + this.browser = browser; +} + +static int /*long*/ eventProc (int /*long*/ handle, int /*long*/ gdkEvent, int /*long*/ pointer) { + int /*long*/ parent = OS.gtk_widget_get_parent (handle); + parent = OS.gtk_widget_get_parent (parent); + if (parent is 0) return 0; + Widget widget = Display.getCurrent ().findWidget (parent); + if (widget !is null && widget instanceof Browser) { + return ((Mozilla)((Browser)widget).webBrowser).delegate.gtk_event (handle, gdkEvent, pointer); + } + return 0; +} + +static Browser findBrowser (int /*long*/ handle) { + /* + * Note. On GTK, Mozilla is embedded into a GtkHBox handle + * and not directly into the parent Composite handle. + */ + int /*long*/ parent = OS.gtk_widget_get_parent (handle); + Display display = Display.getCurrent (); + return (Browser)display.findWidget (parent); +} + +static char[] mbcsToWcs (String codePage, byte [] buffer) { + return Converter.mbcsToWcs (codePage, buffer); +} + +static byte[] wcsToMbcs (String codePage, String string, bool terminate) { + return Converter.wcsToMbcs (codePage, string, terminate); +} + +int /*long*/ getHandle () { + /* + * Bug in Mozilla Linux GTK. Embedding Mozilla into a GtkFixed + * handle causes problems with some Mozilla plug-ins. For some + * reason, the Flash plug-in causes the child of the GtkFixed + * handle to be resized to 1 when the Flash document is loaded. + * That could be due to gtk_container_resize_children being called + * by Mozilla - or one of its plug-ins - on the GtkFixed handle, + * causing the child of the GtkFixed handle to be resized to 1. + * The workaround is to embed Mozilla into a GtkHBox handle. + */ + embedHandle = OS.gtk_hbox_new (false, 0); + OS.gtk_container_add (browser.handle, embedHandle); + OS.gtk_widget_show (embedHandle); + return embedHandle; +} + +String getLibraryName () { + return "libxpcom.so"; //$NON-NLS-1$ +} + +String getSWTInitLibraryName () { + return "swt-xpcominit"; //$NON-NLS-1$ +} + +int /*long*/ gtk_event (int /*long*/ handle, int /*long*/ gdkEvent, int /*long*/ pointer) { + GdkEvent event = new GdkEvent (); + OS.memmove (event, gdkEvent, GdkEvent.sizeof); + if (event.type is OS.GDK_BUTTON_PRESS) { + if (!hasFocus) browser.setFocus (); + } + + /* + * Stop the propagation of events that are not consumed by Mozilla, before + * they reach the parent embedder. These event have already been received. + */ + if (pointer is STOP_PROPOGATE) return 1; + return 0; +} + +void handleFocus () { + if (hasFocus) return; + hasFocus = true; + listener = new Listener () { + public void handleEvent (Event event) { + if (event.widget is browser) return; + ((Mozilla)browser.webBrowser).Deactivate (); + hasFocus = false; + browser.getDisplay ().removeFilter (DWT.FocusIn, this); + browser.getShell ().removeListener (DWT.Deactivate, this); + listener = null; + } + }; + browser.getDisplay ().addFilter (DWT.FocusIn, listener); + browser.getShell ().addListener (DWT.Deactivate, listener); +} + +void handleMouseDown () { + int shellStyle = browser.getShell ().getStyle (); + if ((shellStyle & DWT.ON_TOP) !is 0 && (((shellStyle & DWT.NO_FOCUS) is 0) || ((browser.getStyle () & DWT.NO_FOCUS) is 0))) { + browser.getDisplay ().asyncExec (new Runnable () { + public void run () { + if (browser is null || browser.isDisposed ()) return; + ((Mozilla)browser.webBrowser).Activate (); + } + }); + } +} + +bool hookEnterExit () { + return false; +} + +void init () { + if (eventCallback is null) { + eventCallback = new Callback (getClass (), "eventProc", 3); //$NON-NLS-1$ + eventProc = eventCallback.getAddress (); + if (eventProc is 0) { + browser.dispose (); + Mozilla.error (DWT.ERROR_NO_MORE_CALLBACKS); + } + } + + /* + * Feature in Mozilla. GtkEvents such as key down, key pressed may be consumed + * by Mozilla and never be received by the parent embedder. The workaround + * is to find the top Mozilla gtk widget that receives all the Mozilla GtkEvents, + * i.e. the first child of the parent embedder. Then hook event callbacks and + * forward the event to the parent embedder before Mozilla received and consumed + * them. + */ + int /*long*/ list = OS.gtk_container_get_children (embedHandle); + if (list !is 0) { + mozillaHandle = OS.g_list_data (list); + OS.g_list_free (list); + + if (mozillaHandle !is 0) { + /* Note. Callback to get events before Mozilla receives and consumes them. */ + OS.g_signal_connect (mozillaHandle, OS.event, eventProc, 0); + + /* + * Note. Callback to get the events not consumed by Mozilla - and to block + * them so that they don't get propagated to the parent handle twice. + * This hook is set after Mozilla and is therefore called after Mozilla's + * handler because GTK dispatches events in their order of registration. + */ + OS.g_signal_connect (mozillaHandle, OS.key_press_event, eventProc, STOP_PROPOGATE); + OS.g_signal_connect (mozillaHandle, OS.key_release_event, eventProc, STOP_PROPOGATE); + OS.g_signal_connect (mozillaHandle, OS.button_press_event, eventProc, STOP_PROPOGATE); + } + } +} + +bool needsSpinup () { + return true; +} + +void onDispose (int /*long*/ embedHandle) { + if (listener !is null) { + browser.getDisplay ().removeFilter (DWT.FocusIn, listener); + browser.getShell ().removeListener (DWT.Deactivate, listener); + listener = null; + } + browser = null; +} + +void setSize (int /*long*/ embedHandle, int width, int height) { + OS.gtk_widget_set_size_request (embedHandle, width, height); +} + +}