     return if e.entry is @
     @hideSpells()
 
+  onSurfaceCoordinatesShown: (e) ->
+    # Definitely aren't hovering over this.
+    @hideSpells()
+
   showSpells: =>
+    @clearTimeouts()
     @sortSpells()
     @$el.data('bs.popover').options.content = @getSpellListHTML()
     @$el.popover('setContent').popover('show')
     @$el.parent().parent().parent().i18n()
-    clearTimeout @hideSpellsTimeout if @hideSpellsTimeout
-    @hideSpellsTimeout = null
     @popover = @$el.parent().parent().parent().find('.popover')
     @popover.off 'mouseenter mouseleave'
-    @popover.mouseenter (e) => @onMouseEnter()
-    @popover.mouseleave (e) => @onMouseLeave()
+    @popover.mouseenter (e) => @showSpells() if @controlsEnabled
+    @popover.mouseleave (e) => @hideSpells()
     thangID = @thang.id
     @popover.find('code').click (e) ->
       Backbone.Mediator.publish "level-select-sprite", thangID: thangID, spellName: $(@).data 'spell-name'
     Backbone.Mediator.publish 'tome:thang-list-entry-popover-shown', entry: @
 
   hideSpells: =>
+    @clearTimeouts()
     @$el.popover('hide')
-    @hideSpellsTimeout = null
 
   getSpellListHTML: ->
     spellsPopoverTemplate {spells: @spells}

    'surface:frame-changed': "onFrameChanged"
    'level-set-letterbox': 'onSetLetterbox'
    'tome:thang-list-entry-popover-shown': 'onThangListEntryPopoverShown'

  events:
    'click': 'onClick'

  onSetLetterbox: (e) ->
    if e.on then @reasonsToBeDisabled.letterbox = true else delete @reasonsToBeDisabled.letterbox
    @updateControls()

  onDisableControls: (e) ->
    return if e.controls and not ('surface' in e.controls)  # disable selection?
    @reasonsToBeDisabled.controls = true
    @updateControls()

  onEnableControls: (e) ->
    delete @reasonsToBeDisabled.controls
    @updateControls()

  updateControls: ->
    enabled = _.keys(@reasonsToBeDisabled).length is 0
    return if enabled is @controlsEnabled
