Skip to content
This repository has been archived by the owner on Feb 17, 2022. It is now read-only.

Only prevent the default browser event handling when the specific event types aren't disabled by the user #10

Merged
merged 4 commits into from Aug 12, 2015

Conversation

jplatte
Copy link
Contributor

@jplatte jplatte commented Mar 11, 2015

Extended version of / resolves #4

}
}

/* if we prevent keydown, we won't get keypress
* also we need to ALWAYS prevent backspace and tab otherwise chrome takes action and does bad navigation UX
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think preventing default backspace and tab handling even if the user ignores SDL_KEYUP / SDL_KEYDOWN events is not a good idea, but this is debatable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change breaks text input, we need to make sure that we don't prevent keydown otherwise we won't get any keypress events.

Something like this should fix text input and also only prevent default if KEYUP/DOWN are enabled.

    SDL_bool prevent_default = SDL_GetEventState(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_KEYDOWN : SDL_KEYUP) == SDL_ENABLE;

    if (eventType == EMSCRIPTEN_EVENT_KEYDOWN && SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE && keyEvent->keyCode != 8 /* backspace */ && keyEvent->keyCode != 9 /* tab */)
        prevent_default = SDL_FALSE;

    return prevent_default;

@kripken
Copy link
Member

kripken commented Mar 11, 2015

Some returns of 0 and of 1 are replaced with dynamic checks here - it seems like that could be surprising, we are changing the current behavior?

@jplatte
Copy link
Contributor Author

jplatte commented Mar 11, 2015

Yes, we are changing it like discussed at #4. I didn't notice that one of the returns I changed was a return 0; though. I'll revert that.

@juj
Copy link
Contributor

juj commented Mar 13, 2015

To my understanding, the changes here should be good. If an application has set to ignore specific events altogether, I think it should be just safe to run the default browser behavior in that case.

@@ -420,6 +425,8 @@ Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent *touchEvent, vo
xscale = window_data->window->w / client_w;
yscale = window_data->window->h / client_h;

bool preventDefault = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be SDL_bool, SDL_TRUE/SDL_FALSE here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I forgot C doesn't have booleans. Would SDL_bool really make more sense than int here though, as we have return type int and return this variable in the end?

@jplatte
Copy link
Contributor Author

jplatte commented Mar 29, 2015

Alright, the first test was kind of successful. With

SDL_EventState(SDL_MOUSEWHEEL, SDL_IGNORE);

I can allow the mousewheel to function normally, and with

SDL_EventState(SDL_FINGERDOWN, SDL_IGNORE);
SDL_EventState(SDL_FINGERUP, SDL_IGNORE);
SDL_EventState(SDL_FINGERMOTION, SDL_IGNORE);

I can allow scrolling and zooming on my smartphone. Interestingly, my smartphone seemed to trigger
mousemotion, mouseup and mousedown events as well, meaning I could both scroll on the page and click things in the game I tested this with.

However, I wasn't able to make emscripten allow the default browser actions for keys – I could never navigate the page with my arrow keys, no matter which keyboard events were ignored. I don't know why. I actually tested this with a game that doesn't use keyboard inputs at all, though I don't care a lot whether they are usable for page navigation. Should we revert the keyboard-related changes as they don't work?

Also, there is one other thing I'm unsure about: Emscripten_HandleMouseFocus. This is translated to a SDL_MOUSEMOTION event, but shouldn't it be translated to a SDL_WINDOWEVENT (namely SDL_WINDOWEVENT_ENTER)?

Desktop tests were done in Firefox, Smartphone tests in the Ubuntu Phone default browser app

@Daft-Freak
Copy link
Member

Emscripten_HandleMouseFocus calls SDL_SetMouseFocus which sends the enter/leave events. the extra mousemotion is to update the mouse position when it leaves.

@jplatte
Copy link
Contributor Author

jplatte commented Mar 29, 2015

@Daft-Freak Okay, so what do you think should be returned in that function?

@Daft-Freak
Copy link
Member

SDL_WINDOWEVENT

@jplatte
Copy link
Contributor Author

jplatte commented Mar 29, 2015

Alright, fixed that and also did a rebase, as my fork had merge conflicts. Which means that the only thing left to look after before this can be merged is the keyboard event stuff. For convenience, here is what I wrote about that earlier:

I wasn't able to make emscripten allow the default browser actions for keys – I could never navigate the page with my arrow keys, no matter which keyboard events were ignored. I don't know why. I actually tested this with a game that doesn't use keyboard inputs at all, though I don't care a lot whether they are usable for page navigation. Should we revert the keyboard-related changes as they don't work?

@Daft-Freak
Copy link
Member

It seems to be working in Chrome, but not FIrefox.

@Daft-Freak
Copy link
Member

Okay, so with:

SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE);
SDL_EventState(SDL_KEYDOWN, SDL_DISABLE);
SDL_EventState(SDL_KEYUP, SDL_DISABLE);

keyboard navigation works in Firefox.

@jplatte
Copy link
Contributor Author

jplatte commented Mar 30, 2015

It does? I'll try that again as well, maybe I just did something wrong before :D

@jplatte
Copy link
Contributor Author

jplatte commented Mar 30, 2015

No, for me it still doesn't work. And doNotCaptureKeyboard: true in Module also doesn't work (which I had set all the time) but I guess that was SDL1.x specific the whole time.

@Daft-Freak
Copy link
Member

Hmm, for me it's working. This is what i'm using to test

#include <emscripten/emscripten.h>
#include "SDL.h"

void
loop()
{
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
    }
}

int
main(int argc, char *argv[])
{
    SDL_Window *window;

    /* Initialize SDL */
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        return (1);
    }

    /* Set 640x480 video mode */
    window = SDL_CreateWindow("CheckKeys Test",
                              SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                              640, 480, 0);

    SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE);
    SDL_EventState(SDL_KEYDOWN, SDL_DISABLE);
    SDL_EventState(SDL_KEYUP, SDL_DISABLE);

    emscripten_set_main_loop(loop, 0, 1);

    return (0);
}

Compiled version: https://dl.dropboxusercontent.com/u/17360362/tmp/nokeys.html

@jplatte
Copy link
Contributor Author

jplatte commented Mar 30, 2015

Okay, that one works for me too. I don't know what I did wrong when modifying the game I tested this with before, but I guess I'll be able to figure that out :)

EDIT: I'm not sure why it didn't work before, but now I managed to do it with my game too.

@jplatte
Copy link
Contributor Author

jplatte commented Mar 31, 2015

@juj @kripken Can this be merged now? :)

@kripken
Copy link
Member

kripken commented Mar 31, 2015

Code looks good, but I think we need to add a test for this in emscripten, so it doesn't break.

Also we should verify that this doesn't affect current tests.

@jplatte
Copy link
Contributor Author

jplatte commented Mar 31, 2015

Okay. I don't have a lot of time in the coming days (so it might take a while), but unless someone else wants to do this, I'll try to create some kind of test for this.

@TelpeNight
Copy link
Contributor

Hi. Sorry I didn't answer for along. As far as I can see this pool request is preferred over my #4 ? Did anyone add test for this?

@jplatte
Copy link
Contributor Author

jplatte commented Jul 19, 2015

Hey, sorry I haven't replied in quite some time. I'm not actively using emscripten anymore and don't plan to do so in the near future, so the motivation isn't there anymore. I would be happy to help anyone try to pick up on this, but I don't think it'll be worth it to get into writing a test for this myself.

@Daft-Freak
Copy link
Member

This doesn't seem to break any existing tests. I'm not sure what a test for this would look like.

@kripken kripken merged commit eebda65 into emscripten-ports:master Aug 12, 2015
@kripken
Copy link
Member

kripken commented Aug 12, 2015

Fair enough. Merged.

Thanks @jplatte!

@Daft-Freak
Copy link
Member

This broke TEXTINPUT events. I've pushed a fix for that, but it probably breaks #21. (Don't currently have a working chrome install to test)

@kripken
Copy link
Member

kripken commented Aug 13, 2015

Can you please add a test for TEXTINPUT, so this doesn't regress again? In browser.test_sdl2_key in emscripten I think it would be easy to add.

@Daft-Freak
Copy link
Member

I'll try and get a test done soon.

Daft-Freak pushed a commit that referenced this pull request Oct 20, 2016
Robert Folland

When running this little test program with SDL2 on Wayland it often crashes in SDL_Init.

From a backtrace it is apparent that there is a race condition in creating a xkb_context_ref. Sometimes it is 0x0.

By moving the relevant lines higher up in Wayland_VideoInit (in SDL2-2.0.4/src/video/wayland/SDL_waylandvideo.c:302) this seems to get fixed.

I moved the call to WAYLAND_xkb_context_new() up to before the call to WAYLAND_wl_display_connect().

Here is the test program (just a loop of init and quit), and a backtrace from gdb:

#include <cstdio>
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <unistd.h>
#include <iostream>

int main(int argc, char **argv)
{
    int count = atoi(argv[1]);

    for (int i = 0; i < count; i++) {
        std::cout << "Init " << i << std::endl;
        if (SDL_Init(SDL_INIT_VIDEO) < 0) {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
                         "Couldn't initialize SDL: %s\n",
                         SDL_GetError());
            return 1;
        }
        std::cout << "Quit" << std::endl;
        SDL_Quit();
    }
    return 0;
}


Init 12
Quit
Init 13

Program received signal SIGSEGV, Segmentation fault.
xkb_context_ref (ctx=ctx@entry=0x0) at src/context.c:156
156         ctx->refcnt++;
(gdb) bt
#0  xkb_context_ref (ctx=ctx@entry=0x0) at src/context.c:156
#1  0x00007ffff5e1cd4c in xkb_keymap_new (ctx=0x0, format=XKB_KEYMAP_FORMAT_TEXT_V1, flags=flags@entry=XKB_KEYMAP_COMPILE_NO_FLAGS) at src/keymap-priv.c:65
#2  0x00007ffff5e1c6cc in xkb_keymap_new_from_buffer (ctx=<optimized out>,
    buffer=0x7ffff7fd5000 "xkb_keymap {\nxkb_keycodes \"(unnamed)\" {\n\tminimum = 8;\n\tmaximum = 255;\n\t<ESC>", ' ' <repeats 16 times>, "= 9;\n\t<AE01>", ' ' <re
peats 15 times>, "= 10;\n\t<AE02>", ' ' <repeats 15 times>, "= 11;\n\t<AE03>", ' ' <repeats 15 times>, "= 12;\n\t<AE04>", ' ' <repeats 12 times>..., length=48090,
    format=<optimized out>, flags=<optimized out>) at src/keymap.c:191
#3  0x00007ffff7b8ea4e in keyboard_handle_keymap (data=0x6169b0, keyboard=<optimized out>, format=<optimized out>, fd=5, size=48091)
    at /home/vlab/abs/sdl2/src/SDL2-2.0.4/src/video/wayland/SDL_waylandevents.c:269
#4  0x00007ffff64501f0 in ffi_call_unix64 () from /usr/lib/libffi.so.6
#5  0x00007ffff644fc58 in ffi_call () from /usr/lib/libffi.so.6
#6  0x00007ffff665be3e in wl_closure_invoke (closure=closure@entry=0x61f000, flags=flags@entry=1, target=<optimized out>, target@entry=0x616d20,
    opcode=opcode@entry=0, data=<optimized out>) at src/connection.c:949
#7  0x00007ffff6658be0 in dispatch_event (display=<optimized out>, queue=<optimized out>) at src/wayland-client.c:1274
#8  0x00007ffff6659db4 in dispatch_queue (queue=0x617398, display=0x6172d0) at src/wayland-client.c:1420
#9  wl_display_dispatch_queue_pending (display=0x6172d0, queue=0x617398) at src/wayland-client.c:1662
#10 0x00007ffff665a0cf in wl_display_roundtrip_queue (display=0x6172d0, queue=0x617398) at src/wayland-client.c:1085
#11 0x00007ffff7b8faa0 in Wayland_VideoInit (_this=<optimized out>) at /home/vlab/abs/sdl2/src/SDL2-2.0.4/src/video/wayland/SDL_waylandvideo.c:302
#12 0x00007ffff7b7aed6 in SDL_VideoInit_REAL (driver_name=<optimized out>, driver_name@entry=0x0) at /home/vlab/abs/sdl2/src/SDL2-2.0.4/src/video/SDL_video.c:513
#13 0x00007ffff7ae0ee7 in SDL_InitSubSystem_REAL (flags=16416) at /home/vlab/abs/sdl2/src/SDL2-2.0.4/src/SDL.c:173
#14 0x0000000000400b24 in main (argc=2, argv=0x7fffffffebb8) at vplay-init.cpp:13
(gdb)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants