36
36
static xcb_generic_event_t * ev = NULL ;
37
37
static void (* events [XCB_NO_OPERATION ])(xcb_generic_event_t * e );
38
38
static unsigned int numlockmask = 0 ;
39
- int sigcode = 0 ; // Signal code. Non-zero if we've been interruped by a signal.
39
+ static bool is_sloppy = true; // by default use sloppy focus
40
+ int sigcode = 0 ; // Signal code. Non-zero if we've been interruped by a signal.
40
41
xcb_connection_t * conn = NULL ; // Connection to X server.
41
42
xcb_ewmh_connection_t * ewmh = NULL ; // Ewmh Connection.
42
43
xcb_screen_t * screen = NULL ; // Our current screen.
43
- int randrbase = 0 ; // Beginning of RANDR extension events.
44
+ int randrbase = 0 ; // Beginning of RANDR extension events.
44
45
static uint8_t curws = 0 ; // Current workspace.
45
46
struct client * focuswin = NULL ; // Current focus window.
46
47
static xcb_drawable_t top_win = 0 ; // Window always on top.
@@ -844,6 +845,7 @@ newwin(xcb_generic_event_t *ev)
844
845
XCB_NONE
845
846
};
846
847
848
+
847
849
/* The window is trying to map itself on the current workspace,
848
850
* but since it's unmapped it probably belongs on another workspace.*/
849
851
if (NULL != findclient (& e -> window ))
@@ -887,6 +889,8 @@ newwin(xcb_generic_event_t *ev)
887
889
888
890
if (!client -> maxed )
889
891
setborders (client ,true);
892
+ // always focus new window
893
+ setfocus (client );
890
894
}
891
895
892
896
/* Set border colour, width and event mask for window. */
@@ -2798,8 +2802,26 @@ void
2798
2802
buttonpress (xcb_generic_event_t * ev )
2799
2803
{
2800
2804
xcb_button_press_event_t * e = (xcb_button_press_event_t * )ev ;
2805
+ struct client * client ;
2801
2806
unsigned int i ;
2802
2807
2808
+
2809
+ if (!is_sloppy && e -> detail == XCB_BUTTON_INDEX_1
2810
+ && CLEANMASK (e -> state ) == 0 ) {
2811
+ // skip if already focused
2812
+ if (NULL != focuswin && e -> event == focuswin -> id ) {
2813
+ return ;
2814
+ }
2815
+ client = findclient (& e -> event );
2816
+ if (NULL != client ) {
2817
+ setfocus (client );
2818
+ raisewindow (client -> id );
2819
+ centerpointer (client -> id ,client );
2820
+ setborders (client ,true);
2821
+ }
2822
+ return ;
2823
+ }
2824
+
2803
2825
for (i = 0 ; i < LENGTH (buttons ); i ++ )
2804
2826
if (buttons [i ].func && buttons [i ].button == e -> detail
2805
2827
&& CLEANMASK (buttons [i ].mask )
@@ -2895,6 +2917,13 @@ enternotify(xcb_generic_event_t *ev)
2895
2917
{
2896
2918
xcb_enter_notify_event_t * e = (xcb_enter_notify_event_t * )ev ;
2897
2919
struct client * client ;
2920
+ unsigned int modifiers [] = {
2921
+ 0 ,
2922
+ XCB_MOD_MASK_LOCK ,
2923
+ numlockmask ,
2924
+ numlockmask | XCB_MOD_MASK_LOCK
2925
+ };
2926
+
2898
2927
2899
2928
/*
2900
2929
* If this isn't a normal enter notify, don't bother. We also need
@@ -2907,6 +2936,7 @@ enternotify(xcb_generic_event_t *ev)
2907
2936
* to change focus in those cases.
2908
2937
*/
2909
2938
2939
+
2910
2940
if (e -> mode == XCB_NOTIFY_MODE_NORMAL
2911
2941
|| e -> mode == XCB_NOTIFY_MODE_UNGRAB ) {
2912
2942
/* If we're entering the same window we focus now,
@@ -2915,6 +2945,7 @@ enternotify(xcb_generic_event_t *ev)
2915
2945
if (NULL != focuswin && e -> event == focuswin -> id )
2916
2946
return ;
2917
2947
2948
+
2918
2949
/* Otherwise, set focus to the window we just entered if we
2919
2950
* can find it among the windows we know about.
2920
2951
* If not, just keep focus in the old window. */
@@ -2923,6 +2954,30 @@ enternotify(xcb_generic_event_t *ev)
2923
2954
if (NULL == client )
2924
2955
return ;
2925
2956
2957
+ /* skip this if not is_sloppy
2958
+ * we'll focus on click instead (see buttonpress function)
2959
+ * thus we have to grab left click button on that window
2960
+ * the grab is removed at the end of the setfocus function,
2961
+ * in the grabbuttons when not in sloppy mode
2962
+ */
2963
+ if (!is_sloppy ) {
2964
+ for (unsigned int m = 0 ; m < LENGTH (modifiers ); m ++ ) {
2965
+ xcb_grab_button (conn ,
2966
+ 0 , // owner_events => 0 means
2967
+ // the grab_window won't
2968
+ // receive this event
2969
+ client -> id ,
2970
+ XCB_EVENT_MASK_BUTTON_PRESS ,
2971
+ XCB_GRAB_MODE_ASYNC ,
2972
+ XCB_GRAB_MODE_ASYNC ,
2973
+ screen -> root , XCB_NONE ,
2974
+ XCB_BUTTON_INDEX_1 ,
2975
+ modifiers [m ]
2976
+ );
2977
+ }
2978
+ return ;
2979
+ }
2980
+
2926
2981
setfocus (client );
2927
2982
setborders (client ,true);
2928
2983
}
@@ -3063,6 +3118,19 @@ grabbuttons(struct client *c)
3063
3118
buttons [b ].mask |modifiers [m ]
3064
3119
);
3065
3120
}
3121
+
3122
+ /* ungrab the left click, otherwise we can't use it
3123
+ * we've previously grabbed the left click in the enternotify function
3124
+ * when not in sloppy mode
3125
+ * though the name is counter-intuitive to the method
3126
+ */
3127
+ for (unsigned int m = 0 ; m < LENGTH (modifiers ); m ++ ) {
3128
+ xcb_ungrab_button (conn ,
3129
+ XCB_BUTTON_INDEX_1 ,
3130
+ c -> id ,
3131
+ modifiers [m ]
3132
+ );
3133
+ }
3066
3134
}
3067
3135
3068
3136
void
0 commit comments