Merge branch 'feature/window_focus'
This commit is contained in:
commit
e2b3cdacc2
@ -403,6 +403,7 @@ public:
|
|||||||
/// on the previous thread first if it was active.
|
/// on the previous thread first if it was active.
|
||||||
/// Only one window can be active on a thread at a time, thus
|
/// Only one window can be active on a thread at a time, thus
|
||||||
/// the window previously active (if any) automatically gets deactivated.
|
/// the window previously active (if any) automatically gets deactivated.
|
||||||
|
/// This is not to be confused with requestFocus().
|
||||||
///
|
///
|
||||||
/// \param active True to activate, false to deactivate
|
/// \param active True to activate, false to deactivate
|
||||||
///
|
///
|
||||||
@ -411,6 +412,35 @@ public:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool setActive(bool active = true) const;
|
bool setActive(bool active = true) const;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Request the current window to be made the active
|
||||||
|
/// foreground window
|
||||||
|
///
|
||||||
|
/// At any given time, only one window may have the input focus
|
||||||
|
/// to receive input events such as keystrokes or mouse events.
|
||||||
|
/// If a window requests focus, it only hints to the operating
|
||||||
|
/// system, that it would like to be focused. The operating system
|
||||||
|
/// is free to deny the request.
|
||||||
|
/// This is not to be confused with setActive().
|
||||||
|
///
|
||||||
|
/// \see hasFocus
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void requestFocus();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Check whether the window has the input focus
|
||||||
|
///
|
||||||
|
/// At any given time, only one window may have the input focus
|
||||||
|
/// to receive input events such as keystrokes or most mouse
|
||||||
|
/// events.
|
||||||
|
///
|
||||||
|
/// \return True if window has focus, false otherwise
|
||||||
|
/// \see requestFocus
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool hasFocus() const;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Display on screen what has been rendered to the window so far
|
/// \brief Display on screen what has been rendered to the window so far
|
||||||
///
|
///
|
||||||
|
@ -181,6 +181,21 @@ void WindowImplAndroid::setKeyRepeatEnabled(bool enabled)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void WindowImplAndroid::requestFocus()
|
||||||
|
{
|
||||||
|
// Not applicable
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool WindowImplAndroid::hasFocus() const
|
||||||
|
{
|
||||||
|
// Not applicable
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplAndroid::forwardEvent(const Event& event)
|
void WindowImplAndroid::forwardEvent(const Event& event)
|
||||||
{
|
{
|
||||||
|
@ -154,6 +154,21 @@ public:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual void setKeyRepeatEnabled(bool enabled);
|
virtual void setKeyRepeatEnabled(bool enabled);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Request the current window to be made the active
|
||||||
|
/// foreground window
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual void requestFocus();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Check whether the window has the input focus
|
||||||
|
///
|
||||||
|
/// \return True if window has focus, false otherwise
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual bool hasFocus() const;
|
||||||
|
|
||||||
static void forwardEvent(const Event& event);
|
static void forwardEvent(const Event& event);
|
||||||
static WindowImplAndroid* singleInstance;
|
static WindowImplAndroid* singleInstance;
|
||||||
|
|
||||||
|
@ -187,6 +187,26 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)requestFocus
|
||||||
|
{
|
||||||
|
// Note: this doesn't imply that the view will get any event.
|
||||||
|
// The user has to make sure events are forwarded to the view
|
||||||
|
// with the usual responder chain.
|
||||||
|
[[m_view window] makeKeyAndOrderFront:nil];
|
||||||
|
|
||||||
|
// In case the app is not active, make its dock icon bounce for one sec
|
||||||
|
[NSApp requestUserAttention:NSInformationalRequest];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
-(BOOL)hasFocus
|
||||||
|
{
|
||||||
|
return [NSApp keyWindow] == [m_view window];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)enableKeyRepeat
|
-(void)enableKeyRepeat
|
||||||
{
|
{
|
||||||
|
@ -451,6 +451,23 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(void)requestFocus
|
||||||
|
{
|
||||||
|
[m_window makeKeyAndOrderFront:nil];
|
||||||
|
|
||||||
|
// In case the app is not active, make its dock icon bounce for one sec
|
||||||
|
[NSApp requestUserAttention:NSInformationalRequest];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
-(BOOL)hasFocus
|
||||||
|
{
|
||||||
|
return [NSApp keyWindow] == m_window;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)enableKeyRepeat
|
-(void)enableKeyRepeat
|
||||||
{
|
{
|
||||||
|
@ -320,6 +320,21 @@ public:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual void setKeyRepeatEnabled(bool enabled);
|
virtual void setKeyRepeatEnabled(bool enabled);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Request the current window to be made the active
|
||||||
|
/// foreground window
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual void requestFocus();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Check whether the window has the input focus
|
||||||
|
///
|
||||||
|
/// \return True if window has focus, false otherwise
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual bool hasFocus() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -552,6 +552,20 @@ void WindowImplCocoa::setKeyRepeatEnabled(bool enabled)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void WindowImplCocoa::requestFocus()
|
||||||
|
{
|
||||||
|
[m_delegate requestFocus];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool WindowImplCocoa::hasFocus() const
|
||||||
|
{
|
||||||
|
return [m_delegate hasFocus];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace priv
|
} // namespace priv
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
@ -166,6 +166,21 @@ namespace sf {
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(void)closeWindow;
|
-(void)closeWindow;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Request the current window to be made the active
|
||||||
|
/// foreground window
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
-(void)requestFocus;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Check whether the window has the input focus
|
||||||
|
///
|
||||||
|
/// \return True if window has focus, false otherwise
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
-(BOOL)hasFocus;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Enable key repeat
|
/// \brief Enable key repeat
|
||||||
///
|
///
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#ifdef SFML_OPENGL_ES
|
#ifdef SFML_OPENGL_ES
|
||||||
#include <SFML/Window/EglContext.hpp>
|
#include <SFML/Window/EglContext.hpp>
|
||||||
@ -54,10 +55,11 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
sf::priv::WindowImplX11* fullscreenWindow = NULL;
|
sf::priv::WindowImplX11* fullscreenWindow = NULL;
|
||||||
unsigned long eventMask = FocusChangeMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
|
std::vector<sf::priv::WindowImplX11*> allWindows;
|
||||||
PointerMotionMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask |
|
unsigned long eventMask = FocusChangeMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
|
||||||
EnterWindowMask | LeaveWindowMask;
|
PointerMotionMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask |
|
||||||
|
EnterWindowMask | LeaveWindowMask;
|
||||||
|
|
||||||
// Filter the events received by windows (only allow those matching a specific window)
|
// Filter the events received by windows (only allow those matching a specific window)
|
||||||
Bool checkEvent(::Display*, XEvent* event, XPointer userData)
|
Bool checkEvent(::Display*, XEvent* event, XPointer userData)
|
||||||
@ -192,7 +194,7 @@ m_useSizeHints(false)
|
|||||||
{
|
{
|
||||||
static const unsigned long MWM_HINTS_FUNCTIONS = 1 << 0;
|
static const unsigned long MWM_HINTS_FUNCTIONS = 1 << 0;
|
||||||
static const unsigned long MWM_HINTS_DECORATIONS = 1 << 1;
|
static const unsigned long MWM_HINTS_DECORATIONS = 1 << 1;
|
||||||
|
|
||||||
//static const unsigned long MWM_DECOR_ALL = 1 << 0;
|
//static const unsigned long MWM_DECOR_ALL = 1 << 0;
|
||||||
static const unsigned long MWM_DECOR_BORDER = 1 << 1;
|
static const unsigned long MWM_DECOR_BORDER = 1 << 1;
|
||||||
static const unsigned long MWM_DECOR_RESIZEH = 1 << 2;
|
static const unsigned long MWM_DECOR_RESIZEH = 1 << 2;
|
||||||
@ -207,7 +209,7 @@ m_useSizeHints(false)
|
|||||||
static const unsigned long MWM_FUNC_MINIMIZE = 1 << 3;
|
static const unsigned long MWM_FUNC_MINIMIZE = 1 << 3;
|
||||||
static const unsigned long MWM_FUNC_MAXIMIZE = 1 << 4;
|
static const unsigned long MWM_FUNC_MAXIMIZE = 1 << 4;
|
||||||
static const unsigned long MWM_FUNC_CLOSE = 1 << 5;
|
static const unsigned long MWM_FUNC_CLOSE = 1 << 5;
|
||||||
|
|
||||||
struct WMHints
|
struct WMHints
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@ -216,7 +218,7 @@ m_useSizeHints(false)
|
|||||||
long inputMode;
|
long inputMode;
|
||||||
unsigned long state;
|
unsigned long state;
|
||||||
};
|
};
|
||||||
|
|
||||||
WMHints hints;
|
WMHints hints;
|
||||||
hints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS;
|
hints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS;
|
||||||
hints.decorations = 0;
|
hints.decorations = 0;
|
||||||
@ -250,11 +252,11 @@ m_useSizeHints(false)
|
|||||||
sizeHints->flags = PMinSize | PMaxSize;
|
sizeHints->flags = PMinSize | PMaxSize;
|
||||||
sizeHints->min_width = sizeHints->max_width = width;
|
sizeHints->min_width = sizeHints->max_width = width;
|
||||||
sizeHints->min_height = sizeHints->max_height = height;
|
sizeHints->min_height = sizeHints->max_height = height;
|
||||||
XSetWMNormalHints(m_display, m_window, sizeHints);
|
XSetWMNormalHints(m_display, m_window, sizeHints);
|
||||||
XFree(sizeHints);
|
XFree(sizeHints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the window's WM class (this can be used by window managers)
|
// Set the window's WM class (this can be used by window managers)
|
||||||
char windowClass[512];
|
char windowClass[512];
|
||||||
findExecutableName(windowClass, sizeof(windowClass));
|
findExecutableName(windowClass, sizeof(windowClass));
|
||||||
@ -303,6 +305,9 @@ WindowImplX11::~WindowImplX11()
|
|||||||
|
|
||||||
// Close the connection with the X server
|
// Close the connection with the X server
|
||||||
CloseDisplay(m_display);
|
CloseDisplay(m_display);
|
||||||
|
|
||||||
|
// Remove this window from the global list of windows (required for focus request)
|
||||||
|
allWindows.erase(std::find(allWindows.begin(), allWindows.end(), this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -365,7 +370,7 @@ void WindowImplX11::setSize(const Vector2u& size)
|
|||||||
sizeHints->flags = PMinSize | PMaxSize;
|
sizeHints->flags = PMinSize | PMaxSize;
|
||||||
sizeHints->min_width = sizeHints->max_width = size.x;
|
sizeHints->min_width = sizeHints->max_width = size.x;
|
||||||
sizeHints->min_height = sizeHints->max_height = size.y;
|
sizeHints->min_height = sizeHints->max_height = size.y;
|
||||||
XSetWMNormalHints(m_display, m_window, sizeHints);
|
XSetWMNormalHints(m_display, m_window, sizeHints);
|
||||||
XFree(sizeHints);
|
XFree(sizeHints);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,17 +384,17 @@ void WindowImplX11::setTitle(const String& title)
|
|||||||
{
|
{
|
||||||
// Bare X11 has no Unicode window title support.
|
// Bare X11 has no Unicode window title support.
|
||||||
// There is however an option to tell the window manager your unicode title via hints.
|
// There is however an option to tell the window manager your unicode title via hints.
|
||||||
|
|
||||||
// Convert to UTF-8 encoding.
|
// Convert to UTF-8 encoding.
|
||||||
std::basic_string<Uint8> utf8Title;
|
std::basic_string<Uint8> utf8Title;
|
||||||
Utf32::toUtf8(title.begin(), title.end(), std::back_inserter(utf8Title));
|
Utf32::toUtf8(title.begin(), title.end(), std::back_inserter(utf8Title));
|
||||||
|
|
||||||
// Set the _NET_WM_NAME atom, which specifies a UTF-8 encoded window title.
|
// Set the _NET_WM_NAME atom, which specifies a UTF-8 encoded window title.
|
||||||
Atom wmName = XInternAtom(m_display, "_NET_WM_NAME", False);
|
Atom wmName = XInternAtom(m_display, "_NET_WM_NAME", False);
|
||||||
Atom useUtf8 = XInternAtom(m_display, "UTF8_STRING", False);
|
Atom useUtf8 = XInternAtom(m_display, "UTF8_STRING", False);
|
||||||
XChangeProperty(m_display, m_window, wmName, useUtf8, 8,
|
XChangeProperty(m_display, m_window, wmName, useUtf8, 8,
|
||||||
PropModeReplace, utf8Title.c_str(), utf8Title.size());
|
PropModeReplace, utf8Title.c_str(), utf8Title.size());
|
||||||
|
|
||||||
// Set the non-Unicode title as a fallback for window managers who don't support _NET_WM_NAME.
|
// Set the non-Unicode title as a fallback for window managers who don't support _NET_WM_NAME.
|
||||||
XStoreName(m_display, m_window, title.toAnsiString().c_str());
|
XStoreName(m_display, m_window, title.toAnsiString().c_str());
|
||||||
}
|
}
|
||||||
@ -437,7 +442,7 @@ void WindowImplX11::setIcon(unsigned int width, unsigned int height, const Uint8
|
|||||||
if (i * 8 + k < width)
|
if (i * 8 + k < width)
|
||||||
{
|
{
|
||||||
Uint8 opacity = (pixels[(i * 8 + k + j * width) * 4 + 3] > 0) ? 1 : 0;
|
Uint8 opacity = (pixels[(i * 8 + k + j * width) * 4 + 3] > 0) ? 1 : 0;
|
||||||
maskPixels[i + j * pitch] |= (opacity << k);
|
maskPixels[i + j * pitch] |= (opacity << k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -483,6 +488,67 @@ void WindowImplX11::setKeyRepeatEnabled(bool enabled)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void WindowImplX11::requestFocus()
|
||||||
|
{
|
||||||
|
// Focus is only stolen among SFML windows, not between applications
|
||||||
|
// Check the global list of windows to find out whether an SFML window has the focus
|
||||||
|
// Note: can't handle console and other non-SFML windows belonging to the application.
|
||||||
|
bool sfmlWindowFocused = false;
|
||||||
|
for (std::vector<WindowImplX11*>::iterator itr = allWindows.begin(); itr != allWindows.end(); ++itr)
|
||||||
|
{
|
||||||
|
if ((*itr)->hasFocus())
|
||||||
|
{
|
||||||
|
sfmlWindowFocused = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if window is viewable (not on other desktop, ...)
|
||||||
|
// TODO: Check also if minimized
|
||||||
|
XWindowAttributes attributes;
|
||||||
|
if (XGetWindowAttributes(m_display, m_window, &attributes) == 0)
|
||||||
|
{
|
||||||
|
sf::err() << "Failed to check if window is viewable while requesting focus" << std::endl;
|
||||||
|
return; // error getting attribute
|
||||||
|
}
|
||||||
|
|
||||||
|
bool windowViewable = (attributes.map_state == IsViewable);
|
||||||
|
|
||||||
|
if (sfmlWindowFocused && windowViewable)
|
||||||
|
{
|
||||||
|
// Another SFML window of this application has the focus and the current window is viewable:
|
||||||
|
// steal focus (i.e. bring window to the front and give it input focus)
|
||||||
|
XRaiseWindow(m_display, m_window);
|
||||||
|
XSetInputFocus(m_display, m_window, RevertToPointerRoot, CurrentTime);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Otherwise: display urgency hint (flashing application logo)
|
||||||
|
// Ensure WM hints exist, allocate if necessary
|
||||||
|
XWMHints* hints = XGetWMHints(m_display, m_window);
|
||||||
|
if (hints == NULL)
|
||||||
|
hints = XAllocWMHints();
|
||||||
|
|
||||||
|
// Add urgency (notification) flag to hints
|
||||||
|
hints->flags |= XUrgencyHint;
|
||||||
|
XSetWMHints(m_display, m_window, hints);
|
||||||
|
XFree(hints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool WindowImplX11::hasFocus() const
|
||||||
|
{
|
||||||
|
::Window focusedWindow = 0;
|
||||||
|
int revertToReturn = 0;
|
||||||
|
XGetInputFocus(m_display, &focusedWindow, &revertToReturn);
|
||||||
|
|
||||||
|
return m_window == focusedWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplX11::switchToFullscreen(const VideoMode& mode)
|
void WindowImplX11::switchToFullscreen(const VideoMode& mode)
|
||||||
{
|
{
|
||||||
@ -568,6 +634,9 @@ void WindowImplX11::initialize()
|
|||||||
|
|
||||||
// Flush the commands queue
|
// Flush the commands queue
|
||||||
XFlush(m_display);
|
XFlush(m_display);
|
||||||
|
|
||||||
|
// Add this window to the global list of windows (required for focus request)
|
||||||
|
allWindows.push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -599,7 +668,7 @@ void WindowImplX11::cleanup()
|
|||||||
{
|
{
|
||||||
// Get current screen info
|
// Get current screen info
|
||||||
XRRScreenConfiguration* config = XRRGetScreenInfo(m_display, RootWindow(m_display, m_screen));
|
XRRScreenConfiguration* config = XRRGetScreenInfo(m_display, RootWindow(m_display, m_screen));
|
||||||
if (config)
|
if (config)
|
||||||
{
|
{
|
||||||
// Get the current rotation
|
// Get the current rotation
|
||||||
Rotation currentRotation;
|
Rotation currentRotation;
|
||||||
@ -610,7 +679,7 @@ void WindowImplX11::cleanup()
|
|||||||
|
|
||||||
// Free the configuration instance
|
// Free the configuration instance
|
||||||
XRRFreeScreenConfigInfo(config);
|
XRRFreeScreenConfigInfo(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the fullscreen window
|
// Reset the fullscreen window
|
||||||
fullscreenWindow = NULL;
|
fullscreenWindow = NULL;
|
||||||
@ -680,6 +749,16 @@ bool WindowImplX11::processEvent(XEvent windowEvent)
|
|||||||
Event event;
|
Event event;
|
||||||
event.type = Event::GainedFocus;
|
event.type = Event::GainedFocus;
|
||||||
pushEvent(event);
|
pushEvent(event);
|
||||||
|
|
||||||
|
// If the window has been previously marked urgent (notification) as a result of a focus request, undo that
|
||||||
|
XWMHints* hints = XGetWMHints(m_display, m_window);
|
||||||
|
if (hints != NULL)
|
||||||
|
{
|
||||||
|
// Remove urgency (notification) flag from hints
|
||||||
|
hints->flags &= ~XUrgencyHint;
|
||||||
|
XSetWMHints(m_display, m_window, hints);
|
||||||
|
XFree(hints);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -717,7 +796,7 @@ bool WindowImplX11::processEvent(XEvent windowEvent)
|
|||||||
// Close event
|
// Close event
|
||||||
case ClientMessage:
|
case ClientMessage:
|
||||||
{
|
{
|
||||||
if ((windowEvent.xclient.format == 32) && (windowEvent.xclient.data.l[0]) == static_cast<long>(m_atomClose))
|
if ((windowEvent.xclient.format == 32) && (windowEvent.xclient.data.l[0]) == static_cast<long>(m_atomClose))
|
||||||
{
|
{
|
||||||
Event event;
|
Event event;
|
||||||
event.type = Event::Closed;
|
event.type = Event::Closed;
|
||||||
@ -823,7 +902,7 @@ bool WindowImplX11::processEvent(XEvent windowEvent)
|
|||||||
case Button2: event.mouseButton.button = Mouse::Middle; break;
|
case Button2: event.mouseButton.button = Mouse::Middle; break;
|
||||||
case Button3: event.mouseButton.button = Mouse::Right; break;
|
case Button3: event.mouseButton.button = Mouse::Right; break;
|
||||||
case 8: event.mouseButton.button = Mouse::XButton1; break;
|
case 8: event.mouseButton.button = Mouse::XButton1; break;
|
||||||
case 9: event.mouseButton.button = Mouse::XButton2; break;
|
case 9: event.mouseButton.button = Mouse::XButton2; break;
|
||||||
}
|
}
|
||||||
pushEvent(event);
|
pushEvent(event);
|
||||||
}
|
}
|
||||||
@ -846,7 +925,7 @@ bool WindowImplX11::processEvent(XEvent windowEvent)
|
|||||||
case Button2: event.mouseButton.button = Mouse::Middle; break;
|
case Button2: event.mouseButton.button = Mouse::Middle; break;
|
||||||
case Button3: event.mouseButton.button = Mouse::Right; break;
|
case Button3: event.mouseButton.button = Mouse::Right; break;
|
||||||
case 8: event.mouseButton.button = Mouse::XButton1; break;
|
case 8: event.mouseButton.button = Mouse::XButton1; break;
|
||||||
case 9: event.mouseButton.button = Mouse::XButton2; break;
|
case 9: event.mouseButton.button = Mouse::XButton2; break;
|
||||||
}
|
}
|
||||||
pushEvent(event);
|
pushEvent(event);
|
||||||
}
|
}
|
||||||
|
@ -154,6 +154,21 @@ public:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual void setKeyRepeatEnabled(bool enabled);
|
virtual void setKeyRepeatEnabled(bool enabled);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Request the current window to be made the active
|
||||||
|
/// foreground window
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual void requestFocus();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Check whether the window has the input focus
|
||||||
|
///
|
||||||
|
/// \return True if window has focus, false otherwise
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual bool hasFocus() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -366,6 +366,40 @@ void WindowImplWin32::setKeyRepeatEnabled(bool enabled)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void WindowImplWin32::requestFocus()
|
||||||
|
{
|
||||||
|
// Allow focus stealing only within the same process; compare PIDs of current and foreground window
|
||||||
|
DWORD thisPid = GetWindowThreadProcessId(m_handle, NULL);
|
||||||
|
DWORD foregroundPid = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
|
||||||
|
|
||||||
|
if (thisPid == foregroundPid)
|
||||||
|
{
|
||||||
|
// The window requesting focus belongs to the same process as the current window: steal focus
|
||||||
|
SetForegroundWindow(m_handle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Different process: don't steal focus, but create a taskbar notification ("flash")
|
||||||
|
FLASHWINFO info;
|
||||||
|
info.cbSize = sizeof(info);
|
||||||
|
info.hwnd = m_handle;
|
||||||
|
info.dwFlags = FLASHW_TRAY;
|
||||||
|
info.dwTimeout = 0;
|
||||||
|
info.uCount = 3;
|
||||||
|
|
||||||
|
FlashWindowEx(&info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool WindowImplWin32::hasFocus() const
|
||||||
|
{
|
||||||
|
return m_handle == GetForegroundWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplWin32::registerWindowClass()
|
void WindowImplWin32::registerWindowClass()
|
||||||
{
|
{
|
||||||
|
@ -153,6 +153,21 @@ public:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual void setKeyRepeatEnabled(bool enabled);
|
virtual void setKeyRepeatEnabled(bool enabled);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Request the current window to be made the active
|
||||||
|
/// foreground window
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual void requestFocus();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Check whether the window has the input focus
|
||||||
|
///
|
||||||
|
/// \return True if window has focus, false otherwise
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual bool hasFocus() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -337,6 +337,22 @@ bool Window::setActive(bool active) const
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
void Window::requestFocus()
|
||||||
|
{
|
||||||
|
if (m_impl)
|
||||||
|
m_impl->requestFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool Window::hasFocus() const
|
||||||
|
{
|
||||||
|
return m_impl && m_impl->hasFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Window::display()
|
void Window::display()
|
||||||
{
|
{
|
||||||
// Display the backbuffer on screen
|
// Display the backbuffer on screen
|
||||||
|
@ -194,6 +194,21 @@ public:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual void setKeyRepeatEnabled(bool enabled) = 0;
|
virtual void setKeyRepeatEnabled(bool enabled) = 0;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Request the current window to be made the active
|
||||||
|
/// foreground window
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual void requestFocus() = 0;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Check whether the window has the input focus
|
||||||
|
///
|
||||||
|
/// \return True if window has focus, false otherwise
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual bool hasFocus() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
@ -157,6 +157,21 @@ public:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual void setKeyRepeatEnabled(bool enabled);
|
virtual void setKeyRepeatEnabled(bool enabled);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Request the current window to be made the active
|
||||||
|
/// foreground window
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual void requestFocus();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Check whether the window has the input focus
|
||||||
|
///
|
||||||
|
/// \return True if window has focus, false otherwise
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual bool hasFocus() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using WindowImpl::pushEvent;
|
using WindowImpl::pushEvent;
|
||||||
|
@ -169,6 +169,21 @@ void WindowImplUIKit::setKeyRepeatEnabled(bool enabled)
|
|||||||
// Not applicable
|
// Not applicable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void WindowImplUIKit::requestFocus()
|
||||||
|
{
|
||||||
|
// Not applicable
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool WindowImplUIKit::hasFocus() const
|
||||||
|
{
|
||||||
|
// Not applicable
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SFView* WindowImplUIKit::getGlView() const
|
SFView* WindowImplUIKit::getGlView() const
|
||||||
|
Loading…
Reference in New Issue
Block a user