Displaying a tooltip with GUILayout.Window

I’m having trouble getting GUI.tooltip to work well with GUI Windows and GUILayout. There are two issues:

  1. It seems that GUI.tooltip is only valid inside the Window’s GUI function, but I need to be able to show a tooltip that extends outside the boundaries of the Window.
  2. The tooltip needs to display even if the window is not focused.

Because I’m using GUILayout instead of GUI, I can’t check if the mouse position is inside the component’s rectangle.If anyone could show me how to get the below code working, it would be hugely appreciated!

using UnityEngine;

public class App : MonoBehaviour {
    Rect win1Rect = new Rect(20, 20, 150, 150);

    void OnGUI () {
        GUILayout.BeginArea(win1Rect);
        win1Rect = GUI.Window(0, win1Rect, DoWin1, "Win1");
        GUILayout.EndArea();

        if (GUI.tooltip != "") {
            // Does not work because it's outside of DoWin1
            GUI.Label(new Rect(0, 0, 100, 20), GUI.tooltip);
        }
    }

    void DoWin1 (int windowId) {
        GUILayout.BeginVertical();
        GUILayout.Button(new GUIContent("Button", "Win1 tooltip"));
        GUILayout.EndVertical();
    }
}

GUI.Window (You should actually use GUILayout.Window) works a bit different than other GUI controls. Unity "saves" the data you provide (id,rect,callback, title) internally and handles the windows after OnGUI is finished. That's why you have to use a callback function so Unity can execute the window stuff when it needs to.

To access the tooltip from inside a window outside you have to store it somewhere outside.

Just do something like:

using UnityEngine;

public class App : MonoBehaviour {
    Rect win1Rect = new Rect(20, 20, 150, 150);
    string win1ToolTip = "";

    void OnGUI () {
        GUILayout.BeginArea(win1Rect);
        win1Rect = GUI.Window(0, win1Rect, DoWin1, "Win1");
        GUILayout.EndArea();

        if (win1ToolTip != "") {
            // Does not work because it's outside of DoWin1
            GUI.Label(new Rect(0, 0, 100, 20), win1ToolTip );
        }
    }

    void DoWin1 (int windowId) {
        GUILayout.BeginVertical();
        GUILayout.Button(new GUIContent("Button", "Win1 tooltip"));
        GUILayout.EndVertical();
        if (Event.current.type == EventType.Repaint)
            win1ToolTip = GUI.tooltip;
    }
}

It will delay the reaction by one frame because the tooltip change will take affect next frame but usually you can't see such a delay.