Getting keyboard focus to an offscreen widget



Hello everyone,

I have an application with a widget that acts as a front end for a
widget that is held by a GtkOffscreenWindow. The
"pick-embedded-child", "to-embedder" and "from-embedder" signals are
handled and mouse input is successfully redirected to the offscreen
widget. The problem is that I can't get keyboard focus to the
offscreen widget.

I have attached an example application that shows how things are wired.

I take it I need to do something special in response to the
"focus-in-event" signal but I've so far been unsuccessful in getting
focus to the offscreen widget.

Regards,
Daniel Andersson
#include <gtkmm.h>

void no_transform(GdkWindow*, double in_x, double in_y, double *out_x, double *out_y, void*)
{
    *out_x = in_x;
    *out_y = in_y;
}

GdkWindow* pick_offscreen_child(GdkWindow*, double, double, GdkWindow* child)
{
    return child;
}

class Embedder : public Gtk::DrawingArea
{
  public:
    Embedder()
    {
        m_ow.show();
        m_ow.signal_damage_event().connect(
            sigc::mem_fun(this, &Embedder::on_ow_expose_event));
    }

    void add(Gtk::Widget& widget)
    {
        m_ow.add(widget);
    }

  private:
    bool on_focus_in_event(GdkEventFocus*)
    {
        // how to get focus to the Entry that the OffscreenWindow holds?
        return false;
    }

    void on_realize()
    {
        Gtk::DrawingArea::on_realize();

        set_can_focus(true);
        grab_focus();

        GdkWindow* this_window = Gtk::Widget::gobj()->window;
        GdkWindow* ow_window = static_cast<Gtk::Widget&>(m_ow).gobj()->window;

        g_signal_connect(this_window, "pick-embedded-child",
                         G_CALLBACK(pick_offscreen_child), ow_window);

        gdk_offscreen_window_set_embedder(ow_window, this_window);

        g_signal_connect(ow_window, "to-embedder", G_CALLBACK(no_transform), 0);
        g_signal_connect(ow_window, "from-embedder", G_CALLBACK(no_transform), 0);
    }

    bool on_configure_event(GdkEventConfigure*)
    {
        m_ow.set_size_request(get_allocation().get_width(),
                              get_allocation().get_height());

        return true;
    }

    bool on_expose_event(GdkEventExpose* evt)
    {
        if(Glib::RefPtr<Gdk::Window> window = get_window())
        {
            if(Glib::RefPtr<Gdk::Pixbuf> snapshot = m_ow.get_pixbuf())
            {
                Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();

                Gdk::Cairo::set_source_pixbuf(cr, snapshot, 0, 0);
                cr->paint();
            }
        }

        return true;
    }

    bool on_ow_expose_event(GdkEventExpose* evt)
    {
        queue_draw();
        return false;
    }

    Gtk::OffscreenWindow m_ow;
};

int main(int argc, char** argv)
{
    Gtk::Main kit(argc, argv);

    Gtk::Entry embedded;
    embedded.set_text("type here");
    embedded.show();

    Embedder embedder;
    embedder.add(embedded);
    embedder.show();

    Gtk::Window window;
    window.add(embedder);

    Gtk::Main::run(window);
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]