Bring to Back?

With HTML menus I noticed the “bring_to_front” method but I am now trying to take the focus off of the HTML menu and return it back to the main window. I don’t see a method to do this…

you can play with the z-index. z-index only works on positioned elements (position:absolute, position:relative, or position:fixed).

https://www.w3schools.com/cssref/playit.asp?filename=playcss_z-index&preval=2

div#myBox {
  position:absolute;
  background-color:red;
  z-index:1;
}

you call element.focus from an onClick…

john

I think he is asking not for menus (<div>) within dialogs, but about dialogs. Changing the order of windows.

Window management is not much covered in the API (and I also think it should not, users don’t like apps doing funky stuff with other windows or catching focus), but as a complement to bring_to_front switching the main SketchUp window to the same level can be handy in some situations.
What problem are you trying to solve? If it is just keyboard focus (shortcuts or modifier keys), you can just forward the events through a dialog callback. The user would then focus the main window automatically as soon as he/she needs to click there.

Reference:

Note also in this topic I said …


Discussions & code samples over at the SketchUcation forums:

1 Like

Yeah, I’m trying to automatically bring the focus back to the main SketchUp window after starting a tool that also displays an HTML menu.

If the user clicks anywhere within the main window then focus is returned to the main SketchUp window and the problem is averted but if the the user does not click within the main windows and only moves their mouse (pans back and forth) then focus is still on the HTML menu window and it breaks this method within the tool:

def onKeyDown(key, rpt, flags, view)
   if( key == CONSTRAIN_MODIFIER_KEY && rpt == 1 )
        @shift_down_time = Time.now
        
        # if we already have an inference lock, then unlock it
        if( view.inference_locked? )
            view.lock_inference
        elsif( @state == 0 )
            view.lock_inference @ip
        elsif( @state == 1 )
            view.lock_inference @ip, @ip1
        end
    end


	if( key == VK_CONTROL && rpt == 1 )
		if @Switchposition == "LEFT"
			@Switchposition = "CENTER"
		elsif @Switchposition == "RIGHT"	
			@Switchposition = "LEFT"
		elsif @Switchposition == "CENTER"
			@Switchposition = "RIGHT"
		else
			UI.messagebox "Invalid Switch Position."	
		end
	end		
end

It doesn’t really break the plugin but it is a bit annoying for the user if they are not aware of what is happening. By tapping the control key the user is able to toggle the justification of the switch that the tool is inserting (left, center or right).

What about # onMouseEnter (view) :

Then you can use (Gottselig V’s simple dirty workaround) mentioned by DanRathbun above:

class YourTool
  # Dirty method to get the focus back 
  def focus_back
    dummieDlg = UI::WebDialog.new("dummie", true, "dummie", 0, 0, 10000, 10000, true)
    dummieDlg.show()
    dummieDlg.close()
  end   
  
  def onMouseEnter(view)
    focus_back
    # or optionally check if your webdialog(s) is opened 
    focus_back if @my_webdialog.visible? 
  end  
 end 

This is working on Windows but I’m not 100% sure about Mac…

You can hide/close the dialog if the user is finished with it. If the user is still using it I’m not sure if it’s the best idea to move focus to the main window. Is there a problem with having the dialog focused?

I didn’t know this (cool) hack, but probably it is the best solution for your problem!

Still I want to extend a bit on the possibility of forwarding keyboard input from the dialog:
If you go a step back, and imagine you would have written your method

as one method for the Tool event handler and one method that does the business logic:

def onKeyDown(key, rpt, flags, view)
  if key == CONSTRAIN_MODIFIER_KEY && rpt == 1
    do_business_logic1(view)
  elsif key == VK_CONTROL && rpt == 1
    do_business_logic2(view)
  end
end

def do_business_logic1(view)
  @shift_down_time = Time.now
  
  # if we already have an inference lock, then unlock it
  if view.inference_locked?
    view.lock_inference
  elsif @state == 0
    view.lock_inference(@ip)
  elsif @state == 1
    view.lock_inference(@ip, @ip1)
  end
end

…then it takes not much thinking outside the box to call this business logic method from different event handlers. For example from a dialog callback:

window.addEventListener('keydown', function (event) {
  // Example; there are different ways to get key/char/keyCode, also using jQuery, check for compatibility with macOS.
  sketchup.keydown(event.key);
});
dialog.add_action_callback('keydown') { |dlg, js_key|
  case js_key
  when 'Shift'
    do_business_logic1(@view) # Reference to view stored in instance variable (activate)
  when 'Control'
    do_business_logic2(@view)
  end
}

(See KeyboardEvent.key)
You can also store key states in instance variables (tool keydown and dialog keydown set @shift = true, keyup set @shift = false).

For some use cases this can be too complicated, for some use cases this can be suitable.
For example in Ruby Console+, the custom Select Tool is activated from the dialog. The dialog keeps focus for the case that the user wants to continue entering text, but when hovering the 3d viewport the cursor changes depending on modifier keys to give immediate feedback (already before the user clicks an entity).