improve termination sequence on windows, use patterns instead of textures as directory name
This commit is contained in:
@@ -93,23 +93,23 @@ public class MainActivity extends NativeActivity {
|
|||||||
Log.v("PanoPainterJava", "create path failed: " + brush_thumbs.getAbsolutePath());
|
Log.v("PanoPainterJava", "create path failed: " + brush_thumbs.getAbsolutePath());
|
||||||
|
|
||||||
}
|
}
|
||||||
// textures
|
// patterns
|
||||||
File textures = new File(pano_dir.getAbsolutePath(), "textures");
|
File patterns = new File(pano_dir.getAbsolutePath(), "patterns");
|
||||||
if (!textures.exists())
|
if (!patterns.exists())
|
||||||
{
|
{
|
||||||
if (textures.mkdirs())
|
if (patterns.mkdirs())
|
||||||
Log.v("PanoPainterJava", "create path " + textures.getAbsolutePath());
|
Log.v("PanoPainterJava", "create path " + patterns.getAbsolutePath());
|
||||||
else
|
else
|
||||||
Log.v("PanoPainterJava", "create path failed: " + textures.getAbsolutePath());
|
Log.v("PanoPainterJava", "create path failed: " + patterns.getAbsolutePath());
|
||||||
|
|
||||||
}
|
}
|
||||||
File textures_thumbs = new File(textures.getAbsolutePath(), "thumbs");
|
File patterns_thumbs = new File(patterns.getAbsolutePath(), "thumbs");
|
||||||
if (!textures_thumbs.exists())
|
if (!patterns_thumbs.exists())
|
||||||
{
|
{
|
||||||
if (textures_thumbs.mkdirs())
|
if (patterns_thumbs.mkdirs())
|
||||||
Log.v("PanoPainterJava", "create path " + textures_thumbs.getAbsolutePath());
|
Log.v("PanoPainterJava", "create path " + patterns_thumbs.getAbsolutePath());
|
||||||
else
|
else
|
||||||
Log.v("PanoPainterJava", "create path failed: " + textures_thumbs.getAbsolutePath());
|
Log.v("PanoPainterJava", "create path failed: " + patterns_thumbs.getAbsolutePath());
|
||||||
|
|
||||||
}
|
}
|
||||||
// settings
|
// settings
|
||||||
|
|||||||
39
src/app.cpp
39
src/app.cpp
@@ -143,14 +143,14 @@ void App::initLog()
|
|||||||
{
|
{
|
||||||
LOG("error creating brushes thumbs path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
LOG("error creating brushes thumbs path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
||||||
}
|
}
|
||||||
// textures
|
// patterns
|
||||||
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docpath stringByAppendingString:@"/textures"] withIntermediateDirectories:YES attributes:nil error:&err])
|
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docpath stringByAppendingString:@"/patterns"] withIntermediateDirectories:YES attributes:nil error:&err])
|
||||||
{
|
{
|
||||||
LOG("error creating textures path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
LOG("error creating patterns path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
||||||
}
|
}
|
||||||
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docpath stringByAppendingString:@"/textures/thumbs"] withIntermediateDirectories:YES attributes:nil error:&err])
|
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docpath stringByAppendingString:@"/patterns/thumbs"] withIntermediateDirectories:YES attributes:nil error:&err])
|
||||||
{
|
{
|
||||||
LOG("error creating textures thumbs path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
LOG("error creating patterns thumbs path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
||||||
}
|
}
|
||||||
// settings
|
// settings
|
||||||
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docpath stringByAppendingString:@"/settings"] withIntermediateDirectories:YES attributes:nil error:&err])
|
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docpath stringByAppendingString:@"/settings"] withIntermediateDirectories:YES attributes:nil error:&err])
|
||||||
@@ -185,13 +185,13 @@ void App::initLog()
|
|||||||
LOG("error creating brushes thumbs path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
LOG("error creating brushes thumbs path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
||||||
}
|
}
|
||||||
// textures
|
// textures
|
||||||
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docpath stringByAppendingString:@"/textures"] withIntermediateDirectories:YES attributes:nil error:&err])
|
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docpath stringByAppendingString:@"/patterns"] withIntermediateDirectories:YES attributes:nil error:&err])
|
||||||
{
|
{
|
||||||
LOG("error creating brushes path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
LOG("error creating patterns path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
||||||
}
|
}
|
||||||
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docpath stringByAppendingString:@"/textures/thumbs"] withIntermediateDirectories:YES attributes:nil error:&err])
|
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docpath stringByAppendingString:@"/patterns/thumbs"] withIntermediateDirectories:YES attributes:nil error:&err])
|
||||||
{
|
{
|
||||||
LOG("error creating textures thumbs path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
LOG("error creating patterns thumbs path: %s", [[err localizedDescription] cStringUsingEncoding:NSASCIIStringEncoding]);
|
||||||
}
|
}
|
||||||
// settings
|
// settings
|
||||||
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docpath stringByAppendingString:@"/settings"] withIntermediateDirectories:YES attributes:nil error:&err])
|
if (![[NSFileManager defaultManager] createDirectoryAtPath:[docpath stringByAppendingString:@"/settings"] withIntermediateDirectories:YES attributes:nil error:&err])
|
||||||
@@ -237,10 +237,10 @@ void App::initLog()
|
|||||||
if (!PathFileExistsA((data_path + "\\brushes\\thumbs").c_str()))
|
if (!PathFileExistsA((data_path + "\\brushes\\thumbs").c_str()))
|
||||||
CreateDirectoryA((data_path + "\\brushes\\thumbs").c_str(), NULL);
|
CreateDirectoryA((data_path + "\\brushes\\thumbs").c_str(), NULL);
|
||||||
|
|
||||||
if (!PathFileExistsA((data_path + "\\textures").c_str()))
|
if (!PathFileExistsA((data_path + "\\patterns").c_str()))
|
||||||
CreateDirectoryA((data_path + "\\textures").c_str(), NULL);
|
CreateDirectoryA((data_path + "\\patterns").c_str(), NULL);
|
||||||
if (!PathFileExistsA((data_path + "\\textures\\thumbs").c_str()))
|
if (!PathFileExistsA((data_path + "\\patterns\\thumbs").c_str()))
|
||||||
CreateDirectoryA((data_path + "\\textures\\thumbs").c_str(), NULL);
|
CreateDirectoryA((data_path + "\\patterns\\thumbs").c_str(), NULL);
|
||||||
|
|
||||||
if (!PathFileExistsA((data_path + "\\settings").c_str()))
|
if (!PathFileExistsA((data_path + "\\settings").c_str()))
|
||||||
CreateDirectoryA((data_path + "\\settings").c_str(), NULL);
|
CreateDirectoryA((data_path + "\\settings").c_str(), NULL);
|
||||||
@@ -655,17 +655,18 @@ void App::update(float dt)
|
|||||||
redraw = false;
|
redraw = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void App::terminate()
|
void App::terminate()
|
||||||
{
|
{
|
||||||
LOG("App::terminate");
|
LOG("App::terminate");
|
||||||
TextureManager::invalidate();
|
TextureManager::invalidate();
|
||||||
ShaderManager::invalidate();
|
ShaderManager::invalidate();
|
||||||
layout.clear_context();
|
layout.unload();
|
||||||
//brushes->clear_context();
|
uirtt.destroy();
|
||||||
layers->clear_context();
|
m_face_plane.destroy();
|
||||||
color->clear_context();
|
layers.reset();
|
||||||
stroke->clear_context();
|
color.reset();
|
||||||
|
stroke.reset();
|
||||||
|
grid.reset();
|
||||||
rec_stop();
|
rec_stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,12 +60,10 @@ public:
|
|||||||
NodePopupMenu* menu_edit = nullptr;
|
NodePopupMenu* menu_edit = nullptr;
|
||||||
NodePopupMenu* menu_layers = nullptr;
|
NodePopupMenu* menu_layers = nullptr;
|
||||||
NodeBorder* sidebar = nullptr;
|
NodeBorder* sidebar = nullptr;
|
||||||
std::shared_ptr<NodePanelBrush> brushes;
|
|
||||||
std::shared_ptr<NodePanelLayer> layers;
|
std::shared_ptr<NodePanelLayer> layers;
|
||||||
std::shared_ptr<NodePanelColor> color;
|
std::shared_ptr<NodePanelColor> color;
|
||||||
std::shared_ptr<NodePanelStroke> stroke;
|
std::shared_ptr<NodePanelStroke> stroke;
|
||||||
std::shared_ptr<NodePanelGrid> grid;
|
std::shared_ptr<NodePanelGrid> grid;
|
||||||
std::shared_ptr<NodePanelBrushPreset> presets;
|
|
||||||
NodeCanvas* canvas;
|
NodeCanvas* canvas;
|
||||||
Node* current_panel = nullptr;
|
Node* current_panel = nullptr;
|
||||||
NodeScroll* panels;
|
NodeScroll* panels;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
" else if (mode == 2) return vec4(blend_screen(base, stroke, alpha_tot), alpha_tot);\n"\
|
" else if (mode == 2) return vec4(blend_screen(base, stroke, alpha_tot), alpha_tot);\n"\
|
||||||
" else if (mode == 3) return vec4(blend_colorDodge(base, stroke, alpha_tot), alpha_tot);\n"\
|
" else if (mode == 3) return vec4(blend_colorDodge(base, stroke, alpha_tot), alpha_tot);\n"\
|
||||||
" else if (mode == 4) return vec4(blend_overlay(base, stroke, alpha_tot), alpha_tot);\n"\
|
" else if (mode == 4) return vec4(blend_overlay(base, stroke, alpha_tot), alpha_tot);\n"\
|
||||||
" else return vec4(1, 0, 0, 1);\n"\
|
" else return vec4(1.0, 0.0, 0.0, 1.0);\n"\
|
||||||
"}\n"
|
"}\n"
|
||||||
|
|
||||||
#define SHADER_FUNCTION_BLEND_STROKE \
|
#define SHADER_FUNCTION_BLEND_STROKE \
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
" else if (mode == 2) return 1.0-(1.0-base)*(1.0-stroke);\n"\
|
" else if (mode == 2) return 1.0-(1.0-base)*(1.0-stroke);\n"\
|
||||||
" else if (mode == 3) return base/(1.0-stroke);\n"\
|
" else if (mode == 3) return base/(1.0-stroke);\n"\
|
||||||
" else if (mode == 4) return mix(2.0*base*stroke, 1.0-2.0*(1.0-base)*(1.0-stroke), floor(base*2.0));\n"\
|
" else if (mode == 4) return mix(2.0*base*stroke, 1.0-2.0*(1.0-base)*(1.0-stroke), floor(base*2.0));\n"\
|
||||||
" else return 1;\n"\
|
" else return 1.0;\n"\
|
||||||
"}\n"
|
"}\n"
|
||||||
|
|
||||||
#define SHADER_FUNCTION_HSV \
|
#define SHADER_FUNCTION_HSV \
|
||||||
@@ -88,8 +88,8 @@
|
|||||||
" highp float a = 12.9898;\n"\
|
" highp float a = 12.9898;\n"\
|
||||||
" highp float b = 78.233;\n"\
|
" highp float b = 78.233;\n"\
|
||||||
" highp float c = 43758.5453;\n"\
|
" highp float c = 43758.5453;\n"\
|
||||||
" highp float dt= dot(co.xy ,vec2(a,b));\n"\
|
" highp float dt= dot(co.xy, vec2(a,b));\n"\
|
||||||
" highp float sn= mod(dt,3.14);\n"\
|
" highp float sn= mod(dt, 3.14);\n"\
|
||||||
" return fract(sin(sn) * c);\n"\
|
" return fract(sin(sn) * c);\n"\
|
||||||
"}\n"
|
"}\n"
|
||||||
|
|
||||||
@@ -218,16 +218,14 @@ void App::initShaders()
|
|||||||
"uniform mediump float alpha;\n"
|
"uniform mediump float alpha;\n"
|
||||||
"uniform mediump float stroke_alpha;\n"
|
"uniform mediump float stroke_alpha;\n"
|
||||||
"uniform mediump vec2 resolution;\n"
|
"uniform mediump vec2 resolution;\n"
|
||||||
"uniform bool fragUV2;\n"
|
|
||||||
"uniform bool mask;\n"
|
"uniform bool mask;\n"
|
||||||
"in mediump vec2 uv;\n"
|
"in mediump vec2 uv;\n"
|
||||||
"out mediump vec4 frag;\n"
|
"out mediump vec4 frag;\n"
|
||||||
SHADER_FUNCTION_BLUR
|
SHADER_FUNCTION_BLUR
|
||||||
"void main() {\n"
|
"void main() {\n"
|
||||||
" mediump vec2 uv2 = fragUV2 ? (gl_FragCoord.st / resolution) : uv;\n"
|
" mediump vec4 base = texture(tex, uv);\n"
|
||||||
" mediump vec4 base = texture(tex, uv2);\n"
|
|
||||||
" mediump vec4 stroke = texture(tex_stroke, uv);\n"
|
" mediump vec4 stroke = texture(tex_stroke, uv);\n"
|
||||||
" stroke.a = mask ? stroke.a * stroke_alpha * blur(tex_mask, uv2).r : stroke.a * stroke_alpha;\n"
|
" stroke.a = mask ? stroke.a * stroke_alpha * blur(tex_mask, uv).r : stroke.a * stroke_alpha;\n"
|
||||||
" frag = vec4(base.rgb, clamp((base.a - stroke.a) * alpha, 0.0, 1.0));\n"
|
" frag = vec4(base.rgb, clamp((base.a - stroke.a) * alpha, 0.0, 1.0));\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
// TEXTURE COMP DRAW
|
// TEXTURE COMP DRAW
|
||||||
|
|||||||
@@ -6,6 +6,11 @@
|
|||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "node_border.h"
|
#include "node_border.h"
|
||||||
|
|
||||||
|
void LayoutManager::unload()
|
||||||
|
{
|
||||||
|
m_layouts.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void LayoutManager::create()
|
void LayoutManager::create()
|
||||||
{
|
{
|
||||||
m_layouts[const_hash("main")] = std::make_unique<Node>();
|
m_layouts[const_hash("main")] = std::make_unique<Node>();
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class LayoutManager
|
|||||||
public:
|
public:
|
||||||
bool m_loaded = false;
|
bool m_loaded = false;
|
||||||
std::function<void()> on_loaded;
|
std::function<void()> on_loaded;
|
||||||
|
void unload();
|
||||||
void create();
|
void create();
|
||||||
bool load(const char* path);
|
bool load(const char* path);
|
||||||
bool reload();
|
bool reload();
|
||||||
|
|||||||
48
src/main.cpp
48
src/main.cpp
@@ -28,6 +28,13 @@ bool keys[256];
|
|||||||
std::mutex gl_mutex;
|
std::mutex gl_mutex;
|
||||||
std::mutex async_mutex;
|
std::mutex async_mutex;
|
||||||
std::thread::id gl_thread;
|
std::thread::id gl_thread;
|
||||||
|
|
||||||
|
std::thread hmd_renderer;
|
||||||
|
std::thread renderer;
|
||||||
|
int running = -1;
|
||||||
|
std::mutex render_mutex;
|
||||||
|
std::condition_variable render_cv;
|
||||||
|
|
||||||
int gl_count = 0;
|
int gl_count = 0;
|
||||||
std::deque<std::packaged_task<void()>> tasklist;
|
std::deque<std::packaged_task<void()>> tasklist;
|
||||||
std::mutex task_mutex;
|
std::mutex task_mutex;
|
||||||
@@ -606,11 +613,9 @@ int main(int argc, char** argv)
|
|||||||
App::I.redraw = true;
|
App::I.redraw = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
bool running = true;
|
running = 1;
|
||||||
std::mutex render_mutex;
|
|
||||||
std::condition_variable render_cv;
|
|
||||||
|
|
||||||
std::thread renderer([&] {
|
renderer = std::thread([&] {
|
||||||
BT_SetTerminate();
|
BT_SetTerminate();
|
||||||
LOG("start render thread");
|
LOG("start render thread");
|
||||||
const float target_fps = 10;
|
const float target_fps = 10;
|
||||||
@@ -621,7 +626,7 @@ int main(int argc, char** argv)
|
|||||||
float one_sec = 0;
|
float one_sec = 0;
|
||||||
float render_timer = 0;
|
float render_timer = 0;
|
||||||
float frame_timer = 0;
|
float frame_timer = 0;
|
||||||
while(running)
|
while(running == 1)
|
||||||
{
|
{
|
||||||
t1 = GetTickCount();
|
t1 = GetTickCount();
|
||||||
float dt = (float)(t1 - t0) / 1000.0f;
|
float dt = (float)(t1 - t0) / 1000.0f;
|
||||||
@@ -707,12 +712,13 @@ int main(int argc, char** argv)
|
|||||||
const int diff = framerate - (t1 - t0);
|
const int diff = framerate - (t1 - t0);
|
||||||
render_cv.wait_for(lock, std::chrono::milliseconds(diff));
|
render_cv.wait_for(lock, std::chrono::milliseconds(diff));
|
||||||
}
|
}
|
||||||
|
LOG("renderer terminated");
|
||||||
});
|
});
|
||||||
|
|
||||||
std::mutex hmd_render_mutex;
|
std::mutex hmd_render_mutex;
|
||||||
std::condition_variable hmd_render_cv;
|
std::condition_variable hmd_render_cv;
|
||||||
|
|
||||||
std::thread hmd_renderer([&] {
|
hmd_renderer = std::thread([&] {
|
||||||
if (!vive)
|
if (!vive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -722,7 +728,7 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
const float target_tick_rate = 90;
|
const float target_tick_rate = 90;
|
||||||
unsigned long t0 = GetTickCount();
|
unsigned long t0 = GetTickCount();
|
||||||
while (running && vive->Valid())
|
while (running == 1 && vive->Valid())
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(hmd_render_mutex);
|
std::unique_lock<std::mutex> lock(hmd_render_mutex);
|
||||||
unsigned long t1 = GetTickCount();
|
unsigned long t1 = GetTickCount();
|
||||||
@@ -747,18 +753,21 @@ int main(int argc, char** argv)
|
|||||||
async_lock();
|
async_lock();
|
||||||
vive->Terminate();
|
vive->Terminate();
|
||||||
async_unlock();
|
async_unlock();
|
||||||
|
LOG("hmd renderer terminated");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
MSG msg;
|
MSG msg;
|
||||||
LOG("start main loop");
|
LOG("start main loop");
|
||||||
while (running)
|
while (running == 1)
|
||||||
{
|
{
|
||||||
// If there any message in the queue process it
|
// If there any message in the queue process it
|
||||||
auto present = App::I.animate || App::I.redraw ?
|
auto present = App::I.animate || App::I.redraw ?
|
||||||
PeekMessage(&msg, 0, 0, 0, PM_REMOVE) : GetMessage(&msg, 0, 0, 0);
|
PeekMessage(&msg, 0, 0, 0, PM_REMOVE) : GetMessage(&msg, 0, 0, 0);
|
||||||
|
|
||||||
running = !(msg.message == WM_QUIT/* || gl.keys[VK_ESCAPE]*/);
|
if (msg.message == WM_QUIT)
|
||||||
|
running = 0;
|
||||||
|
|
||||||
if (present)
|
if (present)
|
||||||
{
|
{
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
@@ -768,15 +777,9 @@ int main(int argc, char** argv)
|
|||||||
if (!tasklist.empty())
|
if (!tasklist.empty())
|
||||||
render_cv.notify_all();
|
render_cv.notify_all();
|
||||||
}
|
}
|
||||||
render_cv.notify_all();
|
|
||||||
if (renderer.joinable())
|
|
||||||
renderer.join();
|
|
||||||
if (hmd_renderer.joinable())
|
|
||||||
hmd_renderer.join();
|
|
||||||
App::I.terminate();
|
|
||||||
// Clean up
|
// Clean up
|
||||||
WacomTablet::I.terminate();
|
WacomTablet::I.terminate();
|
||||||
//DestroyWindow(hWnd);
|
DestroyWindow(hWnd);
|
||||||
UnregisterClass(className, hInst);
|
UnregisterClass(className, hInst);
|
||||||
LogRemote::I.stop();
|
LogRemote::I.stop();
|
||||||
}
|
}
|
||||||
@@ -793,8 +796,19 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
|
|
||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
|
case WM_DESTROY:
|
||||||
|
if (running != -1)
|
||||||
|
{
|
||||||
|
running = 0;
|
||||||
|
render_cv.notify_all();
|
||||||
|
if (renderer.joinable())
|
||||||
|
renderer.join();
|
||||||
|
if (hmd_renderer.joinable())
|
||||||
|
hmd_renderer.join();
|
||||||
|
App::I.terminate();
|
||||||
|
}
|
||||||
|
break;
|
||||||
case WM_USER_CLOSE:
|
case WM_USER_CLOSE:
|
||||||
DestroyWindow(hWnd);
|
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
break;
|
break;
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
|
|||||||
@@ -405,6 +405,9 @@ void Node::mouse_capture()
|
|||||||
|
|
||||||
void Node::mouse_release()
|
void Node::mouse_release()
|
||||||
{
|
{
|
||||||
|
if (!parent)
|
||||||
|
return;
|
||||||
|
|
||||||
auto& c = root()->current_mouse_capture;
|
auto& c = root()->current_mouse_capture;
|
||||||
auto& s = root()->m_capture_stack;
|
auto& s = root()->m_capture_stack;
|
||||||
|
|
||||||
@@ -427,6 +430,9 @@ void Node::mouse_release()
|
|||||||
|
|
||||||
void Node::key_capture()
|
void Node::key_capture()
|
||||||
{
|
{
|
||||||
|
if (!parent)
|
||||||
|
return;
|
||||||
|
|
||||||
root()->current_key_capture = this;
|
root()->current_key_capture = this;
|
||||||
m_key_captured = true;
|
m_key_captured = true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user