@@ -475,6 +475,44 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
475475 if (wParam == TIMER_AUTOSAVE ) {
476476 autosave_tick ();
477477 }
478+ if (wParam == TIMER_DRAG_SCROLL ) {
479+ Document * doc = current_doc ();
480+ if (doc && g_editor .mouse_captured ) {
481+ POINT pt ;
482+ GetCursorPos (& pt );
483+ ScreenToClient (hwnd , & pt );
484+ int edit_top = DPI (TITLEBAR_H + MENUBAR_H + TABBAR_H );
485+ int edit_bot = g_editor .client_h - DPI (STATUSBAR_H );
486+ int lh = g_editor .line_height ;
487+ int scroll_amt = 0 ;
488+ if (pt .y < edit_top ) {
489+ scroll_amt = - lh * (1 + (edit_top - pt .y ) / (lh * 2 ));
490+ } else if (pt .y > edit_bot ) {
491+ scroll_amt = lh * (1 + (pt .y - edit_bot ) / (lh * 2 ));
492+ }
493+ if (scroll_amt != 0 ) {
494+ doc -> target_scroll_y += scroll_amt ;
495+ if (doc -> target_scroll_y < 0 ) doc -> target_scroll_y = 0 ;
496+ int total_vl = (int )((doc -> mode == MODE_PROSE && doc -> wc .count > 0 ) ? doc -> wc .count : doc -> lc .count );
497+ int max_scroll = total_vl * lh - (edit_bot - edit_top );
498+ if (max_scroll > 0 && doc -> target_scroll_y > max_scroll )
499+ doc -> target_scroll_y = max_scroll ;
500+ doc -> scroll_y = doc -> target_scroll_y ;
501+ /* Clamp mx to text area */
502+ int clamp_mx = pt .x ;
503+ int max_text_x = g_editor .client_w - DPI (SCROLLBAR_W );
504+ if (g_editor .show_minimap ) max_text_x -= DPI (MINIMAP_W );
505+ if (clamp_mx > max_text_x ) clamp_mx = max_text_x ;
506+ bpos pos = mouse_to_pos (clamp_mx , pt .y );
507+ if (doc -> sel_anchor < 0 ) doc -> sel_anchor = doc -> cursor ;
508+ doc -> cursor = pos ;
509+ InvalidateRect (hwnd , NULL , FALSE);
510+ }
511+ } else {
512+ KillTimer (hwnd , TIMER_DRAG_SCROLL );
513+ }
514+ return 0 ;
515+ }
478516 if (wParam == TIMER_SMOOTH ) {
479517 Document * doc = current_doc ();
480518 int needs_invalidate = 0 ;
@@ -684,6 +722,22 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
684722 return 0 ;
685723 }
686724
725+ /* Search bar close button */
726+ if (g_editor .search .active ) {
727+ int bar_h = g_editor .search .replace_active ? DPI (72 ) : DPI (40 );
728+ int bar_w = DPI (460 );
729+ int sb_x = g_editor .client_w - bar_w - DPI (24 );
730+ int sb_y = DPI (TITLEBAR_H + MENUBAR_H + TABBAR_H ) + DPI (8 );
731+ int btn_size = DPI (20 );
732+ int bx = sb_x + bar_w - DPI (12 ) - btn_size ;
733+ int by = sb_y + DPI (10 );
734+ if (mx >= bx && mx < bx + btn_size && my >= by && my < by + btn_size ) {
735+ toggle_search ();
736+ InvalidateRect (hwnd , NULL , FALSE);
737+ return 0 ;
738+ }
739+ }
740+
687741 /* Editor area */
688742 if (my >= DPI (TITLEBAR_H + MENUBAR_H + TABBAR_H ) && my < g_editor .client_h - DPI (STATUSBAR_H )) {
689743 int sb_x = g_editor .client_w - DPI (SCROLLBAR_W );
@@ -924,6 +978,15 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
924978 editor_ensure_cursor_visible ();
925979 InvalidateRect (hwnd , NULL , FALSE);
926980 }
981+
982+ /* Start/stop auto-scroll timer when dragging above/below editor */
983+ int edit_top = DPI (TITLEBAR_H + MENUBAR_H + TABBAR_H );
984+ int edit_bot = g_editor .client_h - DPI (STATUSBAR_H );
985+ if (my < edit_top || my > edit_bot ) {
986+ SetTimer (hwnd , TIMER_DRAG_SCROLL , 30 , NULL );
987+ } else {
988+ KillTimer (hwnd , TIMER_DRAG_SCROLL );
989+ }
927990 }
928991
929992 /* Track titlebar button hover */
@@ -959,6 +1022,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
9591022 }
9601023 if (g_editor .mouse_captured ) {
9611024 g_editor .mouse_captured = 0 ;
1025+ KillTimer (hwnd , TIMER_DRAG_SCROLL );
9621026 ReleaseCapture ();
9631027 }
9641028 return 0 ;
0 commit comments