Trying to embed Cocoa webkit view in Tk Cocoa

View: New views
7 Messages — Rating Filter:   Alert me  

Trying to embed Cocoa webkit view in Tk Cocoa

by Kevin Walzer-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi all,

Trying to embed a Cocoa webkit view in a Tk-Cocoa window, and am having
some trouble. The relevant code is below. This builds, but crashes Wish
when I try to call the command I've defined. What I'm not clear on is
whether I'm correctly getting a handle on the Tk-Cocoa window and
drawing the view in the right place (thought it was the CGContextRef.
Can anyone take a look and tell me if I'm on the right/wrong track? The
comments indicate how I'm approaching this. --Kevin

//define struct to get handle on Tk-Cocoa window, and its context
typedef struct TkCocoaWindow {
     Tk_Window *winPtr;
     NSView *view;
     CGContextRef *context;
} TkCocoaWindow;


int TkWebkitView  (ClientData cd, Tcl_Interp *ip, int objc, Tcl_Obj
*CONST objv[]) {


   //need proper number of args
   if(objc != 2) {
     Tcl_WrongNumArgs(ip, 2, objv, "win");
     return TCL_ERROR;
   }

   char *win;
   Tk_Window tk_win;


   //get path name of window
   win = Tcl_GetString( objv[1] );

   //get handle to window from name
   tk_win = Tk_NameToWindow( ip, win, Tk_MainWindow( ip ) );

   //create autorelease pool

   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];


   //create instance of webview
   WebView *webView = [[WebView alloc] init];

   //draw in the cg context
   webView =  ((TkCocoaWindow*)Tk_WindowId(tk_win))->context;

//release the memory

   [webView release];

   [pool release];

   return TCL_OK;

}



--
Kevin Walzer
Code by Kevin
http://www.codebykevin.com

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Tcl-mac mailing list
tcl-mac@...
https://lists.sourceforge.net/lists/listinfo/tcl-mac

Re: Trying to embed Cocoa webkit view in Tk Cocoa

by Kevin Walzer-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


After doing more work with this, I've gotten a Cocoa window to draw from
inside Tk with a webkit view embedded. It was easy. Draw the window,
call [window setContentView: webKitstuff], and it works fine.

However, I can't seem to find any way to get a handle on an actual Tk
window from Cocoa for purposes of embedding a content view. As others on
the mailing list have noted, it's possible to get a WindowRef from a
Carbon window, but that's not an option with Cocoa.

Looking more closely at the Tk-Cocoa source code, I see all kinds of
ways to get at a Tk window, and even a few calls to [window
setContentView], so I know this can be done, but I'm not sure it can be
easily done from an extension. There don't appear to be any easily-used
public API's for this purpose. I've tried to include "tkMacOSXInt.h" in
my code, but gcc complains about syntax errors in that file (?). And I'm
not sure that that adding webkit to the Tk-Cocoa core is such a good idea...

As a result, I'm going to set this aside for a while. I've gotten a
working build of TkHTML thanks to Georgios Petsasis, so webkit is not
essential.  Would be nice, however.

--Kevin

--
Kevin Walzer
Code by Kevin
http://www.codebykevin.com

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Tcl-mac mailing list
tcl-mac@...
https://lists.sourceforge.net/lists/listinfo/tcl-mac

Re: Trying to embed Cocoa webkit view in Tk Cocoa

by Daniel A. Steffen :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Kevin,

On Sun, Sep 6, 2009 at 22:37, Kevin Walzer<kw@...> wrote:
> Trying to embed a Cocoa webkit view in a Tk-Cocoa window, and am having
> some trouble. The relevant code is below. This builds, but crashes Wish
> when I try to call the command I've defined. What I'm not clear on is
> whether I'm correctly getting a handle on the Tk-Cocoa window and
> drawing the view in the right place

The main entry point to plug custom drawing into TkAqua Cocoa is
TkMacOSXGetRootControl(), this returns the toplevel content NSView for
a given drawable. You can get the containing NSWindow from that view
via -window, although I'm not sure why you would need to, it should
suffice to add your view as a subview of the returned content view.

For a widget based directly on a NSView-subclass like WebView, you may
not actually need to write any code for it to be drawn, the view's
-draw method should be called automatically by standard NSView drawing
traversal.
If it does not, the easiest might be to follow the implementation of
an existing NSView-based widget like tkMacOSXButton.c,
tkMacOSXScrollbar.c or tkMacOSXMenubutton.c (however, these do more
than the smallest possible example would due to requirements for the
standard Tk widgets).

Maybe it would be easier to get started with a simpler view than the
rather complex WebView, I'm sure a basic extension that shows how to
add a simple NSView like NSProgressIndicator would be a useful example
to others as well...

Cheers,

Daniel

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Tcl-mac mailing list
tcl-mac@...
https://lists.sourceforge.net/lists/listinfo/tcl-mac

Re: Trying to embed Cocoa webkit view in Tk Cocoa

by Kevin Walzer-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Daniel,

> The main entry point to plug custom drawing into TkAqua Cocoa is
> TkMacOSXGetRootControl(), this returns the toplevel content NSView for
> a given drawable. You can get the containing NSWindow from that view
> via -window, although I'm not sure why you would need to, it should
> suffice to add your view as a subview of the returned content view.

Thanks for the tip. Is this command publicly available for extensions? I
don't see it defined anywhere but in tkMacOSXSubwindows.c, and
TkMacOSXDrawableView doesn't appear to be a datatype that extensions can
use. Would setting up my extension to use the TEA architecture and
building it in the same directory as the Tcl/Tk source tree give me
access to it? (Right now I'm using a makefile.) What headers should I
include? I also don't see the DrawableView datatype defined in
tkMacOSXInt.h.

Thanks again for your advice...

Kevin



--
Kevin Walzer
Code by Kevin
http://www.codebykevin.com

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Tcl-mac mailing list
tcl-mac@...
https://lists.sourceforge.net/lists/listinfo/tcl-mac

Re: Trying to embed Cocoa webkit view in Tk Cocoa

by Kevin Walzer-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


>
> Thanks for the tip. Is this command publicly available for extensions? I
> don't see it defined anywhere but in tkMacOSXSubwindows.c, and
> TkMacOSXDrawableView doesn't appear to be a datatype that extensions can
> use. Would setting up my extension to use the TEA architecture and
> building it in the same directory as the Tcl/Tk source tree give me
> access to it? (Right now I'm using a makefile.) What headers should I
> include? I also don't see the DrawableView datatype defined in
> tkMacOSXInt.h.
>
>

After looking a bit more, I think I've found what I need in
tkPlatDecls.h. Thanks!

--
Kevin Walzer
Code by Kevin
http://www.codebykevin.com

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Tcl-mac mailing list
tcl-mac@...
https://lists.sourceforge.net/lists/listinfo/tcl-mac

Re: Trying to embed Cocoa webkit view in Tk Cocoa

by Kevin Walzer-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Daniel,

> The main entry point to plug custom drawing into TkAqua Cocoa is
> TkMacOSXGetRootControl(), this returns the toplevel content NSView for
> a given drawable. You can get the containing NSWindow from that view
> via -window, although I'm not sure why you would need to, it should
> suffice to add your view as a subview of the returned content view.
>

This builds, but still crashes after I run [package require
tkwebkitview; ::tkwebkitview::view .f]. Not sure I'm correctly
specifying the Tk_Window. Any advice? Am I close, or am I completely off
the mark?

Relevant code:

int TkWebkitView  (ClientData cd, Tcl_Interp *ip, int objc, Tcl_Obj
*CONST objv[]) {


   //need proper number of args
   if(objc != 2) {
     Tcl_WrongNumArgs(ip, 2, objv, "win");
     return TCL_ERROR;
   }

   NSApplicationLoad();

   char *win;
   Tk_Window *tk_win;

   //get path name of window
   win = Tcl_GetString( objv[1] );
     tk_win = Tk_CreateWindowFromPath(ip, Tk_MainWindow(ip), win, NULL);
     Tk_MakeWindowExist(tk_win);

//get view
     drawable = Tk_WindowId(tk_win);
     targetview = TkMacOSXGetRootControl(drawable);

   //create autorelease pool

   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

   //create instance of webview
   WebView *webView = [[WebView alloc] init];

  [targetview setView:webView];

    [[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL
URLWithString:@"http://www.apple.com"]]];

   [webView release];

   [pool release];

   return TCL_OK;

}


--
Kevin Walzer
Code by Kevin
http://www.codebykevin.com

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Tcl-mac mailing list
tcl-mac@...
https://lists.sourceforge.net/lists/listinfo/tcl-mac

Re: Trying to embed Cocoa webkit view in Tk Cocoa

by Daniel A. Steffen :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Kevin,

On Tue, Sep 8, 2009 at 05:15, Kevin Walzer<kw@...> wrote:
> This builds, but still crashes after I run [package require tkwebkitview;
> ::tkwebkitview::view .f].

"crashing" isn't very specific, best to provide details...

make sure you build with garbage collection enabled (-fobjc-gc),
otherwise your dylib won't load into GCd Tk and may cause an abort()
in the attempt, I'm guessing that could be the "crash" you are seeing?

> Not sure I'm correctly specifying the Tk_Window.
> Any advice? Am I close, or am I completely off the mark?

not sure what exactly this is supposed to do, for one you're not
setting the webView frame, so it doesn't know where to display
anything... also, you don't need NSApplicationLoad() or an
NSAutoreleasePool, TkAqua Cocoa takes care of all that for you.

Moreover, I do not believe you can get around making a proper tk
widget and reacting to some basic Tk events, to integrate with Tk
geometry and drawing, I don't think things will work out otherwise.

The easiest sample implementation of a tk widget is tkSquare.c in
tk/generic, I've whipped up a quick&dirty adaptation of this to use a
WebView (essentially merging in bits from tkMenubutton.c as suggested
earlier), seems to work ok with very little effort:
    http://www.categorifiedcoder.info/tcltk/tkwebview.tar.bz2

The Cocoa-specific bits of tkWebView.m are below for reference,
everything else is pretty standard tk widget boilerplate (e.g. as in
tkSquare.c)

Hope this gets you started, I don't have time to help any further with
this ATM unfortunately

Cheers,

Daniel

--------------------------

static int
WebViewConfigure(
    Tcl_Interp *interp,
    WebViewStruct *webViewPtr)
{
    if (!webViewPtr->webView) {
        WebView *webView = [[WebView alloc]
                initWithFrame:NSMakeRect(0, 0, 1, 1)];
        [[NSGarbageCollector defaultCollector]
                disableCollectorForPointer:webView];
        webViewPtr->webView = webView;
    }
    WebViewGeometry(webViewPtr);
    [[webViewPtr->webView mainFrame] loadRequest:
            [NSURLRequest requestWithURL:[NSURL URLWithString:
            [NSString stringWithUTF8String:
            Tcl_GetStringFromObj(webViewPtr->url, NULL)]]]];
    if (!webViewPtr->updatePending) {
        Tcl_DoWhenIdle(WebViewDisplay, webViewPtr);
        webViewPtr->updatePending = 1;
    }
    return TCL_OK;
}

static void
WebViewDisplay(
    ClientData clientData)
{
    WebViewStruct *webViewPtr = clientData;
    WebView *webView = webViewPtr->webView;
    Tk_Window tkwin = webViewPtr->tkwin;
    Drawable d = Tk_WindowId(tkwin);
    NSView *view = TkMacOSXGetRootControl(d);
    Rect bounds;
    NSRect frame;

    webViewPtr->updatePending = 0;
    if (!tkwin || !Tk_IsMapped(tkwin) || !view || ![view lockFocusIfCanDraw]) {
        return;
    }
    if ([webView superview] != view) {
        [view addSubview:webView];
    }
    TkMacOSXWinBounds((TkWindow*)tkwin, &bounds);
    frame = NSMakeRect(bounds.left, bounds.top, Tk_Width(tkwin),
            Tk_Height(tkwin));
    frame.origin.y = [view bounds].size.height  -
            (frame.origin.y + frame.size.height);
    if (!NSEqualRects(frame, [webView frame])) {
        [webView setFrame:frame];
    }
    [webView displayRectIgnoringOpacity:[webView bounds]];
    [view unlockFocus];
}

static void
WebViewDestroy(
    char *memPtr)
{
    WebViewStruct *webViewPtr = (WebViewStruct *) memPtr;

    [[NSGarbageCollector defaultCollector]
            enableCollectorForPointer:webViewPtr->webView];
    [webViewPtr->webView release];
    ckfree((char *) webViewPtr);
}

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Tcl-mac mailing list
tcl-mac@...
https://lists.sourceforge.net/lists/listinfo/tcl-mac