SnitXSurf

Widget wrapper on Linux Systems for the surf webbrowser

An easy wrapper for the lightweight surf webbrowser on Linux systems to embed an htmlviewer into Tcl/Tk applications . Requires surf and xprop tools. Works on X but not on Wayland as Wayland does not support the Xembed protocol.

Links

WikiDBImage SnitXsurf.png

Source Code:

##############################################################################
#
#  Created By    : Dr. Detlef Groth
#  Created       : Mon Jan 29 05:11:44 2018
#  Last Modified : <180129.0605>
#
#  Description         : A web browser widget for Tcl/Tk using the 
#                  minimimal web browser surf see:
#                  https://surf.suckless.org/ 
#                   
#
#  Notes         : surve can be driven by setting it's x-properties for instance 
#                  using the commandline tool xprop
#                  as surf supports the Xembed protocol it should run without TkXext, but it did not show up without
#  Requirements  : surf and xprop 
#                  on fedora: dnf install surf xprop
#
#  History       : 0.1 initial release 2018-01-29
#        
##############################################################################
#
#  Copyright (c) 2018 Dr. Detlef Groth.
# 
#  License BSD
# 

package require Tk
package require TkXext
package require snit
package provide SnitXSurf 0.1

snit::widget SnitXSurf {
    option -home http://www.duckduckgo.com
    option -search http://duckduckgo.com/?q=
    variable surf
    constructor {args} {
        $self configurelist $args
        # install check
        foreach tool [list surf xprop] {
            set ok [auto_execok $tool]
            if {$ok eq ""} {
                return -code error "please install $tool for usage of SnitXSurf"
            }
        }
        frame $win.f -width 200 -height 200 -container 1
        set sin [open "|surf -e [expr [winfo id $win.f]] dummy  &" r]
        #exec surf -e [expr [winfo id $win.f]] dummy  &
        # in principle we could get the xiud directly
        # but this does not work (yet)
        # -e embeds but surf is invisible still so we need TkXext
        fconfigure $sin -blocking false -buffering none
        fileevent $sin readable [list EmbedSurf $sin]
        set surf [TkXext.find.window *dummy*];
        while {$surf eq ""} {
            after 500
            set surf [TkXext.find.window *dummy*];
            if {[incr x] > 20} {
                break
            }
        }
        if {$surf eq ""} {
            destroy $win.f
            return -code error "unable to find the Surf window"
        }
        
        # as -e did not work for surf on Tk
        TkXext.reparent.window $surf [winfo id $win.f]
        bind $win.f <Configure> [list TkXext.resize.window $surf %w %h]
        pack $win.f -fill both -expand 1
        exec  xprop -id [expr 0x$surf]  -f _SURF_GO 8s -set _SURF_GO $options(-home) &
        bind $win.f <Destroy> [list [mymethod KillSurf] %W]
    }
    method browse {url} {
        exec  xprop -id [expr 0x$surf]  -f _SURF_GO 8s -set _SURF_GO $url &
    }
    method search {keyword} {
        exec  xprop -id [expr 0x$surf]  -f _SURF_GO 8s -set _SURF_GO $options(-search)$keyword &
    }
    method KillSurf {w} {
        TkXext.delete.or.kill $surf
    }
    method EmbedSurf {chan} {
        # not used yet
        # you might use stdout with your own surf version for
        # communicating via stdout
        if {[gets $chan line] < 0} {
            if {[eof $chan]} {
                close $chan
                return
            }
            # Could not read a complete line this time; Tcl's
            # internal buffering will hold the partial line for us
            # until some more data is available over the socket.
        } else {
            puts stdout $line
        }
    }
}

if {$argv0 eq [info script]} {
    if {[llength $argv] <= 1 } {
        SnitXSurf .surf -home http://www.duckduckgo.com
        pack .surf -side top -fill both -expand true
        if {[llength $argv] == 1} {
            .surf browse [lindex $argv 0]
        }
    }
}

Discussion