namespace Graphics {
Display::Display(const string &):
- primary_monitor(0)
+ primary_monitor(0),
+ focus_window(0)
{
Android::MainThread *thread = reinterpret_cast<Android::MainThread *>(Application::get_data());
if(!thread->is_starting_up())
display.remove_window(*this);
display.add_window(*this);
priv->signal_window_acquired.emit(priv->window);
+ signal_got_focus.emit();
break;
case WINDOW_RESIZED:
options.width = ANativeWindow_getWidth(priv->window);
signal_resize.emit(options.width, options.height);
break;
case WINDOW_DESTROYED:
+ signal_lost_focus.emit();
priv->signal_window_lost.emit();
priv->window = 0;
display.remove_window(*this);
Display::Display(const string &):
primary_monitor(0),
- priv(new Private)
+ priv(new Private),
+ focus_window(0)
{
static ErrorDialog err_dlg(0);
case KEY_UP:
case OTHER_MOUSE_DOWN:
case OTHER_MOUSE_UP:
+ signal_got_focus.emit();
signal_input_event.emit(ev);
break;
case MOUSE_MOVED:
#include <cmath>
+#include <sigc++/bind.h>
#include "display.h"
#include "display_private.h"
#include "window.h"
void Display::add_window(Window &wnd)
{
priv->windows[wnd.get_private().window] = &wnd;
+ wnd.signal_got_focus.connect(sigc::bind(sigc::mem_fun(this, &Display::window_got_focus), sigc::ref(wnd)));
+ wnd.signal_lost_focus.connect(sigc::mem_fun(this, &Display::window_lost_focus));
}
void Display::remove_window(Window &wnd)
{
priv->windows.erase(wnd.get_private().window);
+ if(&wnd==focus_window)
+ focus_window = 0;
}
const VideoMode &Display::get_desktop_mode() const
return find_mode(VideoMode(width, height));
}
+void Display::window_got_focus(Window &w)
+{
+ focus_window = &w;
+}
+
+void Display::window_lost_focus()
+{
+ focus_window = 0;
+}
+
void Display::tick()
{
check_error();
+ Window *old_focus = focus_window;
+
while(process_events()) ;
+
+ if(old_focus && !focus_window)
+ signal_lost_focus.emit();
+ else if(!old_focus && focus_window)
+ signal_got_focus.emit();
}
} // namespace Graphics
#include <list>
#include <stdexcept>
#include <string>
+#include <sigc++/signal.h>
#include "errordialog.h"
#include "monitor.h"
#include "videomode.h"
public:
struct Private;
+ sigc::signal<void> signal_got_focus;
+ sigc::signal<void> signal_lost_focus;
+
private:
std::list<Monitor> monitors;
Monitor *primary_monitor;
std::list<VideoMode> modes;
Private *priv;
ErrorDialog *err_dialog;
+ Window *focus_window;
public:
Display(const std::string &disp_name = std::string());
const VideoMode *find_mode(const VideoMode &, float = 0.5f) const;
const VideoMode *find_mode(unsigned, unsigned) const;
+private:
+ void window_got_focus(Window &);
+ void window_lost_focus();
+public:
+ Window *get_focus_window() const { return focus_window; }
+
+public:
void tick();
private:
bool process_events();
objects instead. */
sigc::signal<void, const Event &> signal_input_event;
+ sigc::signal<void> signal_got_focus;
+ sigc::signal<void> signal_lost_focus;
+
sigc::signal<void, int, int> signal_move;
sigc::signal<void, unsigned, unsigned> signal_resize;
sigc::signal<void, unsigned, unsigned, unsigned, unsigned, const Event &> signal_expose;
Display::Display(const string &):
primary_monitor(0),
- priv(new Private)
+ priv(new Private),
+ focus_window(0)
{
static ErrorDialog err_dlg(0);
signal_expose.emit(update_rect.left, update_rect.top, width, height, evnt);
}
break;
+ case WM_SETFOCUS:
+ signal_got_focus.emit();
+ break;
+ case WM_KILLFOCUS:
+ signal_lost_focus.emit();
+ break;
default:
return false;
}
Display::Display(const string &disp_name):
primary_monitor(0),
- priv(new Private)
+ priv(new Private),
+ focus_window(0)
{
if(disp_name.empty())
priv->display = XOpenDisplay(0);
XSetWindowAttributes attr;
attr.override_redirect = options.fullscreen;
- attr.event_mask = ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask|EnterWindowMask|ExposureMask;
+ attr.event_mask = ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask|EnterWindowMask|ExposureMask|FocusChangeMask;
priv->window = XCreateWindow(dpy,
display.get_private().root_window,
case Expose:
signal_expose.emit(ev.xexpose.x, ev.xexpose.y, ev.xexpose.width, ev.xexpose.height, evnt);
break;
+ case FocusIn:
+ signal_got_focus.emit();
+ break;
+ case FocusOut:
+ signal_lost_focus.emit();
+ break;
default:
return false;
}