mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
finish workaround for Vista keyboard issue
This commit is contained in:
parent
8061092d8e
commit
13877e26b1
@ -13,11 +13,14 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "binaryXml.h"
|
||||
#include "p3d_lock.h"
|
||||
#include <sstream>
|
||||
|
||||
|
||||
static const bool debug_xml_output = false;
|
||||
|
||||
static LOCK xml_lock;
|
||||
static bool xml_lock_initialized = false;
|
||||
|
||||
#define DO_BINARY_XML 1
|
||||
|
||||
enum NodeType {
|
||||
@ -251,6 +254,11 @@ read_xml_node(istream &in, char *&buffer, size_t &buffer_length,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
write_xml(ostream &out, TiXmlDocument *doc, ostream &logfile) {
|
||||
if (!xml_lock_initialized) {
|
||||
INIT_LOCK(xml_lock);
|
||||
}
|
||||
ACQUIRE_LOCK(xml_lock);
|
||||
|
||||
#ifdef DO_BINARY_XML
|
||||
// Binary write.
|
||||
write_xml_node(out, doc);
|
||||
@ -274,6 +282,8 @@ write_xml(ostream &out, TiXmlDocument *doc, ostream &logfile) {
|
||||
logout << "sent: " << *doc << "\n";
|
||||
logfile << logout.str() << flush;
|
||||
}
|
||||
|
||||
RELEASE_LOCK(xml_lock);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -291,6 +301,11 @@ write_xml(ostream &out, TiXmlDocument *doc, ostream &logfile) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TiXmlDocument *
|
||||
read_xml(istream &in, ostream &logfile) {
|
||||
if (!xml_lock_initialized) {
|
||||
INIT_LOCK(xml_lock);
|
||||
}
|
||||
ACQUIRE_LOCK(xml_lock);
|
||||
|
||||
#if DO_BINARY_XML
|
||||
// binary read.
|
||||
size_t buffer_length = 128;
|
||||
@ -298,6 +313,7 @@ read_xml(istream &in, ostream &logfile) {
|
||||
TiXmlNode *xnode = read_xml_node(in, buffer, buffer_length, logfile);
|
||||
delete[] buffer;
|
||||
if (xnode == NULL) {
|
||||
RELEASE_LOCK(xml_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -310,6 +326,7 @@ read_xml(istream &in, ostream &logfile) {
|
||||
in >> *doc;
|
||||
if (in.fail() || in.eof()) {
|
||||
delete doc;
|
||||
RELEASE_LOCK(xml_lock);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@ -321,6 +338,7 @@ read_xml(istream &in, ostream &logfile) {
|
||||
logout << "received: " << *doc << "\n";
|
||||
logfile << logout.str() << flush;
|
||||
}
|
||||
|
||||
|
||||
RELEASE_LOCK(xml_lock);
|
||||
return doc;
|
||||
}
|
||||
|
@ -1426,7 +1426,6 @@ void P3DInstance::
|
||||
handle_notify_request(const string &message) {
|
||||
// We look for certain notify events that have particular meaning
|
||||
// to this instance.
|
||||
nout << "Got notify: " << message << "\n";
|
||||
if (message == "onpythonload") {
|
||||
// Once Python is up and running, we can get the actual main
|
||||
// object from the Python side, and merge it with our own.
|
||||
@ -1459,13 +1458,13 @@ handle_notify_request(const string &message) {
|
||||
|
||||
} else if (message == "onwindowopen") {
|
||||
// The process told us that it just succesfully opened its
|
||||
// window. Tear down the splash window.
|
||||
// window. Hide the splash window.
|
||||
_instance_window_opened = true;
|
||||
if (_splash_window != NULL) {
|
||||
delete _splash_window;
|
||||
_splash_window = NULL;
|
||||
_splash_window->set_visible(false);
|
||||
}
|
||||
|
||||
// Guess we won't be using these images any more.
|
||||
for (int i = 0; i < (int)IT_num_image_types; ++i) {
|
||||
_image_files[i].cleanup();
|
||||
}
|
||||
@ -1497,7 +1496,9 @@ handle_notify_request(const string &message) {
|
||||
auth_finished_main_thread();
|
||||
|
||||
} else if (message == "keyboardfocus") {
|
||||
request_keyboard_focus();
|
||||
if (_splash_window != NULL) {
|
||||
_splash_window->request_keyboard_focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1597,19 +1598,6 @@ handle_script_request(const string &operation, P3D_object *object,
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstance::request_keyboard_focus
|
||||
// Access: Private
|
||||
// Description: The Panda window is asking us to manage keyboard
|
||||
// focus in proxy for it. This is used on Vista, where
|
||||
// the Panda window may be disallowed from directly
|
||||
// assigning itself keyboard focus.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstance::
|
||||
request_keyboard_focus() {
|
||||
nout << "request_keyboard_focus\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DInstance::make_splash_window
|
||||
// Access: Private
|
||||
@ -1618,8 +1606,24 @@ request_keyboard_focus() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstance::
|
||||
make_splash_window() {
|
||||
if (_splash_window != NULL || _instance_window_opened) {
|
||||
// Already got one, or we're already showing the real instance.
|
||||
// Should we make the splash window visible?
|
||||
bool make_visible = true;
|
||||
if (_instance_window_opened) {
|
||||
// Not once we've opened the main window.
|
||||
make_visible = false;
|
||||
}
|
||||
|
||||
if (_wparams.get_window_type() != P3D_WT_embedded &&
|
||||
!_stuff_to_download && _auto_start && _p3d_trusted) {
|
||||
// If it's a toplevel or fullscreen window, then we don't want a
|
||||
// splash window unless we have stuff to download, or a button to
|
||||
// display.
|
||||
make_visible = false;
|
||||
}
|
||||
|
||||
if (_splash_window != NULL) {
|
||||
// Already got one.
|
||||
_splash_window->set_visible(make_visible);
|
||||
return;
|
||||
}
|
||||
if (!_got_wparams) {
|
||||
@ -1630,18 +1634,11 @@ make_splash_window() {
|
||||
// We're hidden, and so is the splash window.
|
||||
return;
|
||||
}
|
||||
if (_wparams.get_window_type() != P3D_WT_embedded &&
|
||||
!_stuff_to_download && _auto_start && _p3d_trusted) {
|
||||
// If it's a toplevel or fullscreen window, then we don't want a
|
||||
// splash window unless we have stuff to download, or a button to
|
||||
// display.
|
||||
return;
|
||||
}
|
||||
|
||||
_splash_window = new SplashWindowType(this);
|
||||
_splash_window = new SplashWindowType(this, make_visible);
|
||||
_splash_window->set_wparams(_wparams);
|
||||
_splash_window->set_install_label(_install_label);
|
||||
|
||||
|
||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||
|
||||
// Go get the required images.
|
||||
|
@ -162,7 +162,6 @@ private:
|
||||
void handle_script_request(const string &operation, P3D_object *object,
|
||||
const string &property_name, P3D_object *value,
|
||||
bool needs_response, int unique_id);
|
||||
void request_keyboard_focus();
|
||||
|
||||
void make_splash_window();
|
||||
void set_background_image(ImageType image_type);
|
||||
|
@ -29,8 +29,8 @@
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3DOsxSplashWindow::
|
||||
P3DOsxSplashWindow(P3DInstance *inst) :
|
||||
P3DSplashWindow(inst)
|
||||
P3DOsxSplashWindow(P3DInstance *inst, bool make_visible) :
|
||||
P3DSplashWindow(inst, make_visible)
|
||||
{
|
||||
_install_progress = 0;
|
||||
_got_wparams = false;
|
||||
@ -226,10 +226,13 @@ handle_event(P3D_event_data event) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DOsxSplashWindow::
|
||||
refresh() {
|
||||
if (!_visible) {
|
||||
return;
|
||||
}
|
||||
if (_toplevel_window != NULL) {
|
||||
Rect r = { 0, 0, _win_height, _win_width };
|
||||
InvalWindowRect(_toplevel_window, &r);
|
||||
|
||||
|
||||
} else {
|
||||
_inst->request_refresh();
|
||||
}
|
||||
@ -242,7 +245,7 @@ refresh() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DOsxSplashWindow::
|
||||
paint_window() {
|
||||
if (!_got_wparams) {
|
||||
if (!_visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class P3DOsxSplashWindow : public P3DSplashWindow {
|
||||
public:
|
||||
P3DOsxSplashWindow(P3DInstance *inst);
|
||||
P3DOsxSplashWindow(P3DInstance *inst, bool make_visible);
|
||||
virtual ~P3DOsxSplashWindow();
|
||||
|
||||
virtual void set_wparams(const P3DWindowParams &wparams);
|
||||
|
@ -403,8 +403,6 @@ run_python() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DPythonRun::
|
||||
request_keyboard_focus(P3DCInstance *inst) {
|
||||
cerr << "requesting keyboard focus\n";
|
||||
|
||||
TiXmlDocument doc;
|
||||
TiXmlElement *xrequest = new TiXmlElement("request");
|
||||
xrequest->SetAttribute("instance_id", inst->get_instance_id());
|
||||
@ -509,6 +507,18 @@ handle_command(TiXmlDocument *doc) {
|
||||
setup_window(instance_id, xwparams);
|
||||
}
|
||||
|
||||
} else if (strcmp(cmd, "windows_message") == 0) {
|
||||
assert(!needs_response);
|
||||
// This is a special message that we use to proxy keyboard
|
||||
// events from the parent process down into Panda, a necessary
|
||||
// hack on Vista.
|
||||
int instance_id = 0, msg = 0, wparam = 0, lparam = 0;
|
||||
xcommand->Attribute("instance_id", &instance_id);
|
||||
xcommand->Attribute("msg", &msg);
|
||||
xcommand->Attribute("wparam", &wparam);
|
||||
xcommand->Attribute("lparam", &lparam);
|
||||
send_windows_message(instance_id, msg, wparam, lparam);
|
||||
|
||||
} else if (strcmp(cmd, "exit") == 0) {
|
||||
assert(!needs_response);
|
||||
terminate_session();
|
||||
@ -1362,6 +1372,25 @@ setup_window(P3DCInstance *inst, TiXmlElement *xwparams) {
|
||||
Py_XDECREF(result);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DPythonRun::send_windows_message
|
||||
// Access: Public
|
||||
// Description: This is used to deliver a windows keyboard message to
|
||||
// the Panda process from the parent process, a
|
||||
// necessary hack on Vista.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DPythonRun::
|
||||
send_windows_message(int id, unsigned int msg, int wparam, int lparam) {
|
||||
Instances::iterator ii = _instances.find(id);
|
||||
if (ii == _instances.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
P3DCInstance *inst = (*ii).second;
|
||||
if (inst->_parent_window_handle != (WindowHandle *)NULL) {
|
||||
inst->_parent_window_handle->send_windows_message(msg, wparam, lparam);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DPythonRun::terminate_session
|
||||
@ -1719,7 +1748,7 @@ rt_thread_run() {
|
||||
P3DPythonRun::P3DWindowHandle::
|
||||
P3DWindowHandle(P3DPythonRun *p3dpython, P3DCInstance *inst,
|
||||
const WindowHandle ©) :
|
||||
WindowHandle(copy.get_os_handle()),
|
||||
WindowHandle(copy),
|
||||
_p3dpython(p3dpython),
|
||||
_inst(inst)
|
||||
{
|
||||
|
@ -100,6 +100,8 @@ private:
|
||||
void set_p3d_filename(P3DCInstance *inst, TiXmlElement *xfparams);
|
||||
void setup_window(int id, TiXmlElement *xwparams);
|
||||
void setup_window(P3DCInstance *inst, TiXmlElement *xwparams);
|
||||
|
||||
void send_windows_message(int id, unsigned int msg, int wparam, int lparam);
|
||||
|
||||
void terminate_session();
|
||||
|
||||
@ -108,7 +110,7 @@ private:
|
||||
PyObject *xml_to_pyobj(TiXmlElement *xvalue);
|
||||
|
||||
private:
|
||||
// This subclass of P3DWindowHandle is associated with the parent
|
||||
// This subclass of WindowHandle is associated with the parent
|
||||
// window we are given by the parent process. We use it to add
|
||||
// hooks for communicating with the parent window, for instance to
|
||||
// ask for the parent window to manage keyboard focus when
|
||||
@ -118,13 +120,13 @@ private:
|
||||
P3DWindowHandle(P3DPythonRun *p3dpython, P3DCInstance *inst,
|
||||
const WindowHandle ©);
|
||||
|
||||
protected:
|
||||
virtual void request_keyboard_focus(WindowHandle *child);
|
||||
|
||||
private:
|
||||
P3DPythonRun *_p3dpython;
|
||||
P3DCInstance *_inst;
|
||||
|
||||
protected:
|
||||
virtual void request_keyboard_focus(WindowHandle *child);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
@ -583,6 +583,29 @@ p3dobj_to_xml(P3D_object *obj) {
|
||||
return xvalue;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DSession::send_windows_message
|
||||
// Access: Public
|
||||
// Description: This is called by the splash window to deliver a
|
||||
// windows keyboard message to the Panda process. It
|
||||
// will be called in a sub-thread, but that's OK, since
|
||||
// write_xml() supports locking.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DSession::
|
||||
send_windows_message(P3DInstance *inst, unsigned int msg, int wparam, int lparam) {
|
||||
if (_p3dpython_started) {
|
||||
TiXmlDocument doc;
|
||||
TiXmlElement *xcommand = new TiXmlElement("command");
|
||||
xcommand->SetAttribute("cmd", "windows_message");
|
||||
xcommand->SetAttribute("instance_id", inst->get_instance_id());
|
||||
xcommand->SetAttribute("msg", msg);
|
||||
xcommand->SetAttribute("wparam", wparam);
|
||||
xcommand->SetAttribute("lparam", lparam);
|
||||
doc.LinkEndChild(xcommand);
|
||||
write_xml(_pipe_write, &doc, nout);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DSession::signal_request_ready
|
||||
// Access: Public
|
||||
|
@ -54,6 +54,8 @@ public:
|
||||
TiXmlDocument *command_and_response(TiXmlDocument *command);
|
||||
P3D_object *xml_to_p3dobj(const TiXmlElement *xvalue);
|
||||
TiXmlElement *p3dobj_to_xml(P3D_object *obj);
|
||||
void send_windows_message(P3DInstance *inst, unsigned int msg,
|
||||
int wparam, int lparam);
|
||||
|
||||
void signal_request_ready(P3DInstance *inst);
|
||||
|
||||
|
@ -49,11 +49,12 @@ METHODDEF(void) my_error_exit (j_common_ptr cinfo) {
|
||||
// them both into this class for reference.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3DSplashWindow::
|
||||
P3DSplashWindow(P3DInstance *inst) :
|
||||
P3DSplashWindow(P3DInstance *inst, bool make_visible) :
|
||||
_inst(inst),
|
||||
_fparams(inst->get_fparams()),
|
||||
_wparams(inst->get_wparams())
|
||||
{
|
||||
_visible = make_visible;
|
||||
_button_width = 0;
|
||||
_button_height = 0;
|
||||
_button_x = 0;
|
||||
@ -87,6 +88,20 @@ set_wparams(const P3DWindowParams &wparams) {
|
||||
_wparams = wparams;
|
||||
_win_width = _wparams.get_win_width();
|
||||
_win_height = _wparams.get_win_height();
|
||||
_visible = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DSplashWindow::set_visible
|
||||
// Access: Public, Virtual
|
||||
// Description: Makes the splash window visible or invisible, so as
|
||||
// not to compete with the embedded Panda window in the
|
||||
// same space.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DSplashWindow::
|
||||
set_visible(bool visible) {
|
||||
nout << "P3DSplashWindow::set_visible(" << visible << ")\n";
|
||||
_visible = visible;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -152,6 +167,18 @@ set_button_active(bool flag) {
|
||||
set_mouse_data(_mouse_x, _mouse_y, _mouse_down);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DSplashWindow::request_keyboard_focus
|
||||
// Access: Private
|
||||
// Description: The Panda window is asking us to manage keyboard
|
||||
// focus in proxy for it. This is used on Vista, where
|
||||
// the Panda window may be disallowed from directly
|
||||
// assigning itself keyboard focus.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DSplashWindow::
|
||||
request_keyboard_focus() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DSplashWindow::read_image_data
|
||||
// Access: Protected
|
||||
|
@ -33,7 +33,7 @@ class P3DInstance;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class P3DSplashWindow {
|
||||
public:
|
||||
P3DSplashWindow(P3DInstance *inst);
|
||||
P3DSplashWindow(P3DInstance *inst, bool make_visible);
|
||||
virtual ~P3DSplashWindow();
|
||||
|
||||
inline const P3DFileParams &get_fparams() const;
|
||||
@ -41,6 +41,8 @@ public:
|
||||
virtual void set_wparams(const P3DWindowParams &wparams);
|
||||
inline const P3DWindowParams &get_wparams() const;
|
||||
|
||||
virtual void set_visible(bool visible);
|
||||
|
||||
enum ImagePlacement {
|
||||
IP_background,
|
||||
IP_button_ready,
|
||||
@ -57,6 +59,7 @@ public:
|
||||
virtual bool handle_event(P3D_event_data event);
|
||||
|
||||
virtual void set_button_active(bool flag);
|
||||
virtual void request_keyboard_focus();
|
||||
|
||||
protected:
|
||||
// This ImageData base class provides minimal functionality for
|
||||
@ -96,6 +99,7 @@ protected:
|
||||
P3DFileParams _fparams;
|
||||
P3DWindowParams _wparams;
|
||||
int _win_width, _win_height;
|
||||
bool _visible;
|
||||
|
||||
// The region of the window for accepting button clicks.
|
||||
int _button_width, _button_height;
|
||||
|
@ -16,6 +16,10 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef WM_MOUSEWHEEL
|
||||
#define WM_MOUSEWHEEL 0x20a
|
||||
#endif
|
||||
|
||||
bool P3DWinSplashWindow::_registered_window_class = false;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -24,8 +28,8 @@ bool P3DWinSplashWindow::_registered_window_class = false;
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
P3DWinSplashWindow::
|
||||
P3DWinSplashWindow(P3DInstance *inst) :
|
||||
P3DSplashWindow(inst)
|
||||
P3DWinSplashWindow(P3DInstance *inst, bool make_visible) :
|
||||
P3DSplashWindow(inst, make_visible)
|
||||
{
|
||||
_thread = NULL;
|
||||
_thread_id = 0;
|
||||
@ -36,6 +40,9 @@ P3DWinSplashWindow(P3DInstance *inst) :
|
||||
|
||||
_drawn_bstate = BS_hidden;
|
||||
_drawn_progress = 0.0;
|
||||
_focus_seq = 0;
|
||||
|
||||
_request_focus_tick = 0;
|
||||
|
||||
INIT_LOCK(_install_lock);
|
||||
}
|
||||
@ -68,6 +75,24 @@ set_wparams(const P3DWindowParams &wparams) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DWinSplashWindow::set_visible
|
||||
// Access: Public, Virtual
|
||||
// Description: Makes the splash window visible or invisible, so as
|
||||
// not to compete with the embedded Panda window in the
|
||||
// same space.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DWinSplashWindow::
|
||||
set_visible(bool visible) {
|
||||
P3DSplashWindow::set_visible(visible);
|
||||
|
||||
if (_visible) {
|
||||
ShowWindow(_hwnd, SW_SHOWNORMAL);
|
||||
} else {
|
||||
ShowWindow(_hwnd, SW_HIDE);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DWinSplashWindow::set_image_filename
|
||||
// Access: Public, Virtual
|
||||
@ -166,6 +191,30 @@ set_install_progress(double install_progress) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DWinSplashWindow::request_keyboard_focus
|
||||
// Access: Private
|
||||
// Description: The Panda window is asking us to manage keyboard
|
||||
// focus in proxy for it. This is used on Vista, where
|
||||
// the Panda window may be disallowed from directly
|
||||
// assigning itself keyboard focus.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DWinSplashWindow::
|
||||
request_keyboard_focus() {
|
||||
// Store the time at which we last requested focus.
|
||||
_request_focus_tick = GetTickCount();
|
||||
|
||||
// Increment the _focus_seq to tell the thread to call SetFocus().
|
||||
ACQUIRE_LOCK(_install_lock);
|
||||
++_focus_seq;
|
||||
RELEASE_LOCK(_install_lock);
|
||||
|
||||
if (_thread_id != 0) {
|
||||
// Post a silly message to spin the message loop.
|
||||
PostThreadMessage(_thread_id, WM_USER, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DWinSplashWindow::register_window_class
|
||||
// Access: Public, Static
|
||||
@ -277,6 +326,7 @@ void P3DWinSplashWindow::
|
||||
thread_run() {
|
||||
make_window();
|
||||
|
||||
int last_focus_seq = 0;
|
||||
MSG msg;
|
||||
int retval;
|
||||
retval = GetMessage(&msg, NULL, 0, 0);
|
||||
@ -312,6 +362,14 @@ thread_run() {
|
||||
_drawn_bstate = _bstate;
|
||||
InvalidateRect(_hwnd, NULL, TRUE);
|
||||
}
|
||||
|
||||
if (_focus_seq != last_focus_seq) {
|
||||
last_focus_seq = _focus_seq;
|
||||
if (SetFocus(_hwnd) == NULL && GetLastError() != 0) {
|
||||
nout << "SetFocus(" << _hwnd << ") failed: " << GetLastError() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
RELEASE_LOCK(_install_lock);
|
||||
|
||||
retval = GetMessage(&msg, NULL, 0, 0);
|
||||
@ -396,7 +454,13 @@ make_window() {
|
||||
}
|
||||
}
|
||||
SetWindowLongPtr(_hwnd, GWLP_USERDATA, (LONG_PTR)this);
|
||||
ShowWindow(_hwnd, SW_SHOWNORMAL);
|
||||
nout << "Created splash window " << _hwnd << "\n";
|
||||
|
||||
if (_visible) {
|
||||
ShowWindow(_hwnd, SW_SHOWNORMAL);
|
||||
} else {
|
||||
ShowWindow(_hwnd, SW_HIDE);
|
||||
}
|
||||
|
||||
_blue_brush = CreateSolidBrush(RGB(108, 165, 224));
|
||||
}
|
||||
@ -802,6 +866,41 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
set_mouse_data(_mouse_x, _mouse_y, false);
|
||||
ReleaseCapture();
|
||||
break;
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
// Someone on the desktop is playing games with us. It keeps
|
||||
// wanting to grab the keyboard focus back immediately after we
|
||||
// successfully call SetFocus(). Well, we really mean it, darn it
|
||||
// all. If we got a WM_KILLFOCUS within a few milliseconds of
|
||||
// calling SetFocus(), well, call SetFocus() again, until it
|
||||
// sticks.
|
||||
{
|
||||
int elapsed = GetTickCount() - _request_focus_tick;
|
||||
if (elapsed < 200) {
|
||||
if (SetFocus(_hwnd) == NULL && GetLastError() != 0) {
|
||||
nout << "Secondary SetFocus failed: " << GetLastError() << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Keyboard events that are to be proxied to the Panda window.
|
||||
case WM_MOUSEWHEEL:
|
||||
case WM_IME_SETCONTEXT:
|
||||
case WM_IME_NOTIFY:
|
||||
case WM_IME_STARTCOMPOSITION:
|
||||
case WM_IME_ENDCOMPOSITION:
|
||||
case WM_IME_COMPOSITION:
|
||||
case WM_CHAR:
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_SYSCOMMAND:
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYUP:
|
||||
if (_inst->get_session() != NULL) {
|
||||
_inst->get_session()->send_windows_message(_inst, msg, wparam, lparam);
|
||||
}
|
||||
break;
|
||||
};
|
||||
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
|
@ -31,14 +31,17 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class P3DWinSplashWindow : public P3DSplashWindow {
|
||||
public:
|
||||
P3DWinSplashWindow(P3DInstance *inst);
|
||||
P3DWinSplashWindow(P3DInstance *inst, bool make_visible);
|
||||
virtual ~P3DWinSplashWindow();
|
||||
|
||||
virtual void set_wparams(const P3DWindowParams &wparams);
|
||||
virtual void set_visible(bool visible);
|
||||
|
||||
virtual void set_image_filename(const string &image_filename,
|
||||
ImagePlacement image_placement);
|
||||
virtual void set_install_label(const string &install_label);
|
||||
virtual void set_install_progress(double install_progress);
|
||||
virtual void request_keyboard_focus();
|
||||
|
||||
static void register_window_class();
|
||||
static void unregister_window_class();
|
||||
@ -92,6 +95,9 @@ private:
|
||||
ButtonState _drawn_bstate;
|
||||
string _drawn_label;
|
||||
double _drawn_progress;
|
||||
int _focus_seq;
|
||||
|
||||
int _request_focus_tick;
|
||||
|
||||
bool _thread_continue;
|
||||
bool _thread_running;
|
||||
|
@ -34,7 +34,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class P3DX11SplashWindow : public P3DSplashWindow {
|
||||
public:
|
||||
P3DX11SplashWindow(P3DInstance *inst);
|
||||
P3DX11SplashWindow(P3DInstance *inst, bool make_visible);
|
||||
virtual ~P3DX11SplashWindow();
|
||||
|
||||
virtual void set_wparams(const P3DWindowParams &wparams);
|
||||
|
Loading…
x
Reference in New Issue
Block a user