Patch 9.0.1158
Problem:    Code is indented more than necessary.
Solution:   Use an early return where it makes sense. (Yegappan Lakshmanan,
            closes #11787)
Files:      src/findfile.c, src/fold.c, src/getchar.c, src/gui.c,
            src/gui_beval.c, src/gui_gtk.c, src/gui_gtk_f.c,
            src/gui_gtk_x11.c, src/gui_motif.c, src/gui_photon.c,
            src/gui_w32.c, src/gui_x11.c, src/gui_xim.c


*** ../vim-9.0.1157/src/findfile.c      2022-10-01 19:43:48.606494048 +0100
--- src/findfile.c      2023-01-08 13:38:57.101602496 +0000
***************
*** 1426,1436 ****
  {
      // check for NULL pointer, not to return an error to the user, but
      // to prevent a crash
!     if (stack_ptr != NULL)
!     {
!       stack_ptr->ffs_prev = search_ctx->ffsc_stack_ptr;
!       search_ctx->ffsc_stack_ptr = stack_ptr;
!     }
  }
  
  /*
--- 1426,1436 ----
  {
      // check for NULL pointer, not to return an error to the user, but
      // to prevent a crash
!     if (stack_ptr == NULL)
!       return;
! 
!     stack_ptr->ffs_prev = search_ctx->ffsc_stack_ptr;
!     search_ctx->ffsc_stack_ptr = stack_ptr;
  }
  
  /*
*** ../vim-9.0.1157/src/fold.c  2023-01-02 16:54:48.932860868 +0000
--- src/fold.c  2023-01-08 13:38:57.101602496 +0000
***************
*** 513,525 ****
      void
  foldCheckClose(void)
  {
!     if (*p_fcl != NUL)        // can only be "all" right now
!     {
!       checkupdate(curwin);
!       if (checkCloseRec(&curwin->w_folds, curwin->w_cursor.lnum,
!                                                       (int)curwin->w_p_fdl))
!           changed_window_setting();
!     }
  }
  
  // checkCloseRec() {{{2
--- 513,526 ----
      void
  foldCheckClose(void)
  {
!     if (*p_fcl == NUL)
!       return;
! 
!     // can only be "all" right now
!     checkupdate(curwin);
!     if (checkCloseRec(&curwin->w_folds, curwin->w_cursor.lnum,
!               (int)curwin->w_p_fdl))
!       changed_window_setting();
  }
  
  // checkCloseRec() {{{2
***************
*** 1077,1092 ****
      }
      if (hasFolding(start->lnum, &start->lnum, NULL))
        start->col = 0;
!     if (hasFolding(end->lnum, NULL, &end->lnum))
!     {
!       ptr = ml_get(end->lnum);
!       end->col = (colnr_T)STRLEN(ptr);
!       if (end->col > 0 && *p_sel == 'o')
!           --end->col;
!       // prevent cursor from moving on the trail byte
!       if (has_mbyte)
!           mb_adjust_cursor();
!     }
  }
  
  // cursor_foldstart() {{{2
--- 1078,1094 ----
      }
      if (hasFolding(start->lnum, &start->lnum, NULL))
        start->col = 0;
! 
!     if (!hasFolding(end->lnum, NULL, &end->lnum))
!       return;
! 
!     ptr = ml_get(end->lnum);
!     end->col = (colnr_T)STRLEN(ptr);
!     if (end->col > 0 && *p_sel == 'o')
!       --end->col;
!     // prevent cursor from moving on the trail byte
!     if (has_mbyte)
!       mb_adjust_cursor();
  }
  
  // cursor_foldstart() {{{2
***************
*** 1215,1225 ****
      static void
  checkupdate(win_T *wp)
  {
!     if (wp->w_foldinvalid)
!     {
!       foldUpdate(wp, (linenr_T)1, (linenr_T)MAXLNUM); // will update all
!       wp->w_foldinvalid = FALSE;
!     }
  }
  
  // setFoldRepeat() {{{2
--- 1217,1227 ----
      static void
  checkupdate(win_T *wp)
  {
!     if (!wp->w_foldinvalid)
!       return;
! 
!     foldUpdate(wp, (linenr_T)1, (linenr_T)MAXLNUM); // will update all
!     wp->w_foldinvalid = FALSE;
  }
  
  // setFoldRepeat() {{{2
*** ../vim-9.0.1157/src/getchar.c       2022-11-29 20:33:16.592850638 +0000
--- src/getchar.c       2023-01-08 13:38:57.101602496 +0000
***************
*** 259,269 ****
      if (buf->bh_curr == NULL)
        return;  // nothing to delete
      len = (int)STRLEN(buf->bh_curr->b_str);
!     if (len >= slen)
!     {
!       buf->bh_curr->b_str[len - slen] = NUL;
!       buf->bh_space += slen;
!     }
  }
  
  /*
--- 259,269 ----
      if (buf->bh_curr == NULL)
        return;  // nothing to delete
      len = (int)STRLEN(buf->bh_curr->b_str);
!     if (len < slen)
!       return;
! 
!     buf->bh_curr->b_str[len - slen] = NUL;
!     buf->bh_space += slen;
  }
  
  /*
***************
*** 478,489 ****
      void
  ResetRedobuff(void)
  {
!     if (!block_redo)
!     {
!       free_buff(&old_redobuff);
!       old_redobuff = redobuff;
!       redobuff.bh_first.b_next = NULL;
!     }
  }
  
  /*
--- 478,489 ----
      void
  ResetRedobuff(void)
  {
!     if (block_redo)
!       return;
! 
!     free_buff(&old_redobuff);
!     old_redobuff = redobuff;
!     redobuff.bh_first.b_next = NULL;
  }
  
  /*
***************
*** 493,507 ****
      void
  CancelRedo(void)
  {
!     if (!block_redo)
!     {
!       free_buff(&redobuff);
!       redobuff = old_redobuff;
!       old_redobuff.bh_first.b_next = NULL;
!       start_stuff();
!       while (read_readbuffers(TRUE) != NUL)
!           ;
!     }
  }
  
  /*
--- 493,507 ----
      void
  CancelRedo(void)
  {
!     if (block_redo)
!       return;
! 
!     free_buff(&redobuff);
!     redobuff = old_redobuff;
!     old_redobuff.bh_first.b_next = NULL;
!     start_stuff();
!     while (read_readbuffers(TRUE) != NUL)
!       ;
  }
  
  /*
***************
*** 520,530 ****
  
      // Make a copy, so that ":normal ." in a function works.
      s = get_buffcont(&save_redo->sr_redobuff, FALSE);
!     if (s != NULL)
!     {
!       add_buff(&redobuff, s, -1L);
!       vim_free(s);
!     }
  }
  
  /*
--- 520,530 ----
  
      // Make a copy, so that ":normal ." in a function works.
      s = get_buffcont(&save_redo->sr_redobuff, FALSE);
!     if (s == NULL)
!       return;
! 
!     add_buff(&redobuff, s, -1L);
!     vim_free(s);
  }
  
  /*
***************
*** 944,958 ****
      static void
  init_typebuf(void)
  {
!     if (typebuf.tb_buf == NULL)
!     {
!       typebuf.tb_buf = typebuf_init;
!       typebuf.tb_noremap = noremapbuf_init;
!       typebuf.tb_buflen = TYPELEN_INIT;
!       typebuf.tb_len = 0;
!       typebuf.tb_off = MAXMAPLEN + 4;
!       typebuf.tb_change_cnt = 1;
!     }
  }
  
  /*
--- 944,958 ----
      static void
  init_typebuf(void)
  {
!     if (typebuf.tb_buf != NULL)
!       return;
! 
!     typebuf.tb_buf = typebuf_init;
!     typebuf.tb_noremap = noremapbuf_init;
!     typebuf.tb_buflen = TYPELEN_INIT;
!     typebuf.tb_len = 0;
!     typebuf.tb_off = MAXMAPLEN + 4;
!     typebuf.tb_change_cnt = 1;
  }
  
  /*
***************
*** 1324,1334 ****
      void
  ungetchars(int len)
  {
!     if (reg_recording != 0)
!     {
!       delete_buff_tail(&recordbuff, len);
!       last_recorded_len -= len;
!     }
  }
  
  /*
--- 1324,1334 ----
      void
  ungetchars(int len)
  {
!     if (reg_recording == 0)
!       return;
! 
!     delete_buff_tail(&recordbuff, len);
!     last_recorded_len -= len;
  }
  
  /*
***************
*** 2230,2252 ****
  {
      getchar_common(argvars, rettv);
  
!     if (rettv->v_type == VAR_NUMBER)
!     {
!       char_u          temp[7];   // mbyte-char: 6, NUL: 1
!       varnumber_T     n = rettv->vval.v_number;
!       int             i = 0;
  
!       if (n != 0)
!       {
!           if (has_mbyte)
!               i += (*mb_char2bytes)(n, temp + i);
!           else
!               temp[i++] = n;
!       }
!       temp[i++] = NUL;
!       rettv->v_type = VAR_STRING;
!       rettv->vval.v_string = vim_strsave(temp);
      }
  }
  
  /*
--- 2230,2252 ----
  {
      getchar_common(argvars, rettv);
  
!     if (rettv->v_type != VAR_NUMBER)
!       return;
  
!     char_u            temp[7];   // mbyte-char: 6, NUL: 1
!     varnumber_T       n = rettv->vval.v_number;
!     int               i = 0;
! 
!     if (n != 0)
!     {
!       if (has_mbyte)
!           i += (*mb_char2bytes)(n, temp + i);
!       else
!           temp[i++] = n;
      }
+     temp[i++] = NUL;
+     rettv->v_type = VAR_STRING;
+     rettv->vval.v_string = vim_strsave(temp);
  }
  
  /*
***************
*** 4031,4040 ****
      void
  reset_last_used_map(mapblock_T *mp)
  {
!     if (last_used_map == mp)
!     {
!       last_used_map = NULL;
!       last_used_sid = -1;
!     }
  }
  #endif
--- 4031,4040 ----
      void
  reset_last_used_map(mapblock_T *mp)
  {
!     if (last_used_map != mp)
!       return;
! 
!     last_used_map = NULL;
!     last_used_sid = -1;
  }
  #endif
*** ../vim-9.0.1157/src/gui.c   2022-11-22 12:40:44.066427878 +0000
--- src/gui.c   2023-01-08 13:38:57.105602496 +0000
***************
*** 1171,1241 ****
        return;
  
      gui_check_pos();
-     if (!gui.cursor_is_valid || force
-                   || gui.row != gui.cursor_row || gui.col != gui.cursor_col)
-     {
-       gui_undraw_cursor();
  
!       // If a cursor-less sleep is ongoing, leave the cursor invisible
!       if (cursor_is_sleeping())
!           return;
  
!       if (gui.row < 0)
!           return;
  #ifdef HAVE_INPUT_METHOD
!       if (gui.row != gui.cursor_row || gui.col != gui.cursor_col)
!           im_set_position(gui.row, gui.col);
  #endif
!       gui.cursor_row = gui.row;
!       gui.cursor_col = gui.col;
  
!       // Only write to the screen after ScreenLines[] has been initialized
!       if (!screen_cleared || ScreenLines == NULL)
!           return;
  
!       // Clear the selection if we are about to write over it
!       if (clear_selection)
!           clip_may_clear_selection(gui.row, gui.row);
!       // Check that the cursor is inside the shell (resizing may have made
!       // it invalid)
!       if (gui.row >= screen_Rows || gui.col >= screen_Columns)
!           return;
  
!       gui.cursor_is_valid = TRUE;
  
!       /*
!        * How the cursor is drawn depends on the current mode.
!        * When in a terminal window use the shape/color specified there.
!        */
  #ifdef FEAT_TERMINAL
!       if (terminal_is_active())
!           shape = term_get_cursor_shape(&shape_fg, &shape_bg);
!       else
  #endif
!           shape = &shape_table[get_shape_idx(FALSE)];
!       if (State & MODE_LANGMAP)
!           id = shape->id_lm;
!       else
!           id = shape->id;
  
!       // get the colors and attributes for the cursor.  Default is inverted
!       cfg = INVALCOLOR;
!       cbg = INVALCOLOR;
!       cattr = HL_INVERSE;
!       gui_mch_set_blinking(shape->blinkwait,
!                            shape->blinkon,
!                            shape->blinkoff);
!       if (shape->blinkwait == 0 || shape->blinkon == 0
!                                                      || shape->blinkoff == 0)
!           gui_mch_stop_blink(FALSE);
  #ifdef FEAT_TERMINAL
!       if (shape_bg != INVALCOLOR)
!       {
!           cattr = 0;
!           cfg = shape_fg;
!           cbg = shape_bg;
!       }
!       else
  #endif
        if (id > 0)
        {
--- 1171,1243 ----
        return;
  
      gui_check_pos();
  
!     if (gui.cursor_is_valid && !force
!               && gui.row == gui.cursor_row && gui.col == gui.cursor_col)
!       return;
  
!     gui_undraw_cursor();
! 
!     // If a cursor-less sleep is ongoing, leave the cursor invisible
!     if (cursor_is_sleeping())
!       return;
! 
!     if (gui.row < 0)
!       return;
  #ifdef HAVE_INPUT_METHOD
!     if (gui.row != gui.cursor_row || gui.col != gui.cursor_col)
!       im_set_position(gui.row, gui.col);
  #endif
!     gui.cursor_row = gui.row;
!     gui.cursor_col = gui.col;
  
!     // Only write to the screen after ScreenLines[] has been initialized
!     if (!screen_cleared || ScreenLines == NULL)
!       return;
  
!     // Clear the selection if we are about to write over it
!     if (clear_selection)
!       clip_may_clear_selection(gui.row, gui.row);
!     // Check that the cursor is inside the shell (resizing may have made
!     // it invalid)
!     if (gui.row >= screen_Rows || gui.col >= screen_Columns)
!       return;
  
!     gui.cursor_is_valid = TRUE;
  
!     /*
!      * How the cursor is drawn depends on the current mode.
!      * When in a terminal window use the shape/color specified there.
!      */
  #ifdef FEAT_TERMINAL
!     if (terminal_is_active())
!       shape = term_get_cursor_shape(&shape_fg, &shape_bg);
!     else
  #endif
!       shape = &shape_table[get_shape_idx(FALSE)];
!     if (State & MODE_LANGMAP)
!       id = shape->id_lm;
!     else
!       id = shape->id;
  
!     // get the colors and attributes for the cursor.  Default is inverted
!     cfg = INVALCOLOR;
!     cbg = INVALCOLOR;
!     cattr = HL_INVERSE;
!     gui_mch_set_blinking(shape->blinkwait,
!           shape->blinkon,
!           shape->blinkoff);
!     if (shape->blinkwait == 0 || shape->blinkon == 0
!           || shape->blinkoff == 0)
!       gui_mch_stop_blink(FALSE);
  #ifdef FEAT_TERMINAL
!     if (shape_bg != INVALCOLOR)
!     {
!       cattr = 0;
!       cfg = shape_fg;
!       cbg = shape_bg;
!     }
!     else
  #endif
        if (id > 0)
        {
***************
*** 1251,1257 ****
  # else
                        im_get_status()
  # endif
!                       )
                {
                    iid = syn_name2id((char_u *)"CursorIM");
                    if (iid > 0)
--- 1253,1259 ----
  # else
                        im_get_status()
  # endif
!                  )
                {
                    iid = syn_name2id((char_u *)"CursorIM");
                    if (iid > 0)
***************
*** 1267,1398 ****
  #endif
        }
  
!       /*
!        * Get the attributes for the character under the cursor.
!        * When no cursor color was given, use the character color.
!        */
!       attr = ScreenAttrs[LineOffset[gui.row] + gui.col];
!       if (attr > HL_ALL)
!           aep = syn_gui_attr2entry(attr);
!       if (aep != NULL)
!       {
!           attr = aep->ae_attr;
!           if (cfg == INVALCOLOR)
!               cfg = ((attr & HL_INVERSE)  ? aep->ae_u.gui.bg_color
!                                           : aep->ae_u.gui.fg_color);
!           if (cbg == INVALCOLOR)
!               cbg = ((attr & HL_INVERSE)  ? aep->ae_u.gui.fg_color
!                                           : aep->ae_u.gui.bg_color);
!       }
        if (cfg == INVALCOLOR)
!           cfg = (attr & HL_INVERSE) ? gui.back_pixel : gui.norm_pixel;
        if (cbg == INVALCOLOR)
!           cbg = (attr & HL_INVERSE) ? gui.norm_pixel : gui.back_pixel;
  
  #ifdef FEAT_XIM
!       if (aep != NULL)
!       {
!           xim_bg_color = ((attr & HL_INVERSE) ? aep->ae_u.gui.fg_color
!                                               : aep->ae_u.gui.bg_color);
!           xim_fg_color = ((attr & HL_INVERSE) ? aep->ae_u.gui.bg_color
!                                               : aep->ae_u.gui.fg_color);
!           if (xim_bg_color == INVALCOLOR)
!               xim_bg_color = (attr & HL_INVERSE) ? gui.norm_pixel
!                                                  : gui.back_pixel;
!           if (xim_fg_color == INVALCOLOR)
!               xim_fg_color = (attr & HL_INVERSE) ? gui.back_pixel
!                                                  : gui.norm_pixel;
!       }
!       else
!       {
            xim_bg_color = (attr & HL_INVERSE) ? gui.norm_pixel
!                                              : gui.back_pixel;
            xim_fg_color = (attr & HL_INVERSE) ? gui.back_pixel
!                                              : gui.norm_pixel;
!       }
  #endif
  
!       attr &= ~HL_INVERSE;
!       if (cattr & HL_INVERSE)
!       {
!           cc = cbg;
!           cbg = cfg;
!           cfg = cc;
!       }
!       cattr &= ~HL_INVERSE;
  
        /*
!        * When we don't have window focus, draw a hollow cursor.
         */
!       if (!gui.in_focus)
        {
!           gui_mch_draw_hollow_cursor(cbg);
!           return;
        }
! 
!       old_hl_mask = gui.highlight_mask;
!       if (shape->shape == SHAPE_BLOCK)
        {
!           /*
!            * Draw the text character with the cursor colors.  Use the
!            * character attributes plus the cursor attributes.
!            */
!           gui.highlight_mask = (cattr | attr);
!           (void)gui_screenchar(LineOffset[gui.row] + gui.col,
!                       GUI_MON_IS_CURSOR | GUI_MON_NOCLEAR, cfg, cbg, 0);
        }
!       else
        {
! #if defined(FEAT_RIGHTLEFT)
!           int     col_off = FALSE;
! #endif
!           /*
!            * First draw the partial cursor, then overwrite with the text
!            * character, using a transparent background.
!            */
!           if (shape->shape == SHAPE_VER)
!           {
!               cur_height = gui.char_height;
!               cur_width = (gui.char_width * shape->percentage + 99) / 100;
!           }
!           else
            {
!               cur_height = (gui.char_height * shape->percentage + 99) / 100;
!               cur_width = gui.char_width;
            }
-           if (has_mbyte && (*mb_off2cells)(LineOffset[gui.row] + gui.col,
-                                   LineOffset[gui.row] + screen_Columns) > 1)
-           {
-               // Double wide character.
-               if (shape->shape != SHAPE_VER)
-                   cur_width += gui.char_width;
- #ifdef FEAT_RIGHTLEFT
-               if (CURSOR_BAR_RIGHT)
-               {
-                   // gui.col points to the left half of the character but
-                   // the vertical line needs to be on the right half.
-                   // A double-wide horizontal line is also drawn from the
-                   // right half in gui_mch_draw_part_cursor().
-                   col_off = TRUE;
-                   ++gui.col;
-               }
  #endif
!           }
!           gui_mch_draw_part_cursor(cur_width, cur_height, cbg);
  #if defined(FEAT_RIGHTLEFT)
!           if (col_off)
!               --gui.col;
  #endif
  
  #ifndef FEAT_GUI_MSWIN            // doesn't seem to work for MSWindows
!           gui.highlight_mask = ScreenAttrs[LineOffset[gui.row] + gui.col];
!           (void)gui_screenchar(LineOffset[gui.row] + gui.col,
!                   GUI_MON_TRS_CURSOR | GUI_MON_NOCLEAR,
!                   (guicolor_T)0, (guicolor_T)0, 0);
  #endif
-       }
-       gui.highlight_mask = old_hl_mask;
      }
  }
  
  #if defined(FEAT_MENU) || defined(PROTO)
--- 1269,1399 ----
  #endif
        }
  
!     /*
!      * Get the attributes for the character under the cursor.
!      * When no cursor color was given, use the character color.
!      */
!     attr = ScreenAttrs[LineOffset[gui.row] + gui.col];
!     if (attr > HL_ALL)
!       aep = syn_gui_attr2entry(attr);
!     if (aep != NULL)
!     {
!       attr = aep->ae_attr;
        if (cfg == INVALCOLOR)
!           cfg = ((attr & HL_INVERSE)  ? aep->ae_u.gui.bg_color
!                   : aep->ae_u.gui.fg_color);
        if (cbg == INVALCOLOR)
!           cbg = ((attr & HL_INVERSE)  ? aep->ae_u.gui.fg_color
!                   : aep->ae_u.gui.bg_color);
!     }
!     if (cfg == INVALCOLOR)
!       cfg = (attr & HL_INVERSE) ? gui.back_pixel : gui.norm_pixel;
!     if (cbg == INVALCOLOR)
!       cbg = (attr & HL_INVERSE) ? gui.norm_pixel : gui.back_pixel;
  
  #ifdef FEAT_XIM
!     if (aep != NULL)
!     {
!       xim_bg_color = ((attr & HL_INVERSE) ? aep->ae_u.gui.fg_color
!               : aep->ae_u.gui.bg_color);
!       xim_fg_color = ((attr & HL_INVERSE) ? aep->ae_u.gui.bg_color
!               : aep->ae_u.gui.fg_color);
!       if (xim_bg_color == INVALCOLOR)
            xim_bg_color = (attr & HL_INVERSE) ? gui.norm_pixel
!               : gui.back_pixel;
!       if (xim_fg_color == INVALCOLOR)
            xim_fg_color = (attr & HL_INVERSE) ? gui.back_pixel
!               : gui.norm_pixel;
!     }
!     else
!     {
!       xim_bg_color = (attr & HL_INVERSE) ? gui.norm_pixel
!           : gui.back_pixel;
!       xim_fg_color = (attr & HL_INVERSE) ? gui.back_pixel
!           : gui.norm_pixel;
!     }
  #endif
  
!     attr &= ~HL_INVERSE;
!     if (cattr & HL_INVERSE)
!     {
!       cc = cbg;
!       cbg = cfg;
!       cfg = cc;
!     }
!     cattr &= ~HL_INVERSE;
! 
!     /*
!      * When we don't have window focus, draw a hollow cursor.
!      */
!     if (!gui.in_focus)
!     {
!       gui_mch_draw_hollow_cursor(cbg);
!       return;
!     }
  
+     old_hl_mask = gui.highlight_mask;
+     if (shape->shape == SHAPE_BLOCK)
+     {
        /*
!        * Draw the text character with the cursor colors.      Use the
!        * character attributes plus the cursor attributes.
         */
!       gui.highlight_mask = (cattr | attr);
!       (void)gui_screenchar(LineOffset[gui.row] + gui.col,
!               GUI_MON_IS_CURSOR | GUI_MON_NOCLEAR, cfg, cbg, 0);
!     }
!     else
!     {
! #if defined(FEAT_RIGHTLEFT)
!       int         col_off = FALSE;
! #endif
!       /*
!        * First draw the partial cursor, then overwrite with the text
!        * character, using a transparent background.
!        */
!       if (shape->shape == SHAPE_VER)
        {
!           cur_height = gui.char_height;
!           cur_width = (gui.char_width * shape->percentage + 99) / 100;
        }
!       else
        {
!           cur_height = (gui.char_height * shape->percentage + 99) / 100;
!           cur_width = gui.char_width;
        }
!       if (has_mbyte && (*mb_off2cells)(LineOffset[gui.row] + gui.col,
!                   LineOffset[gui.row] + screen_Columns) > 1)
        {
!           // Double wide character.
!           if (shape->shape != SHAPE_VER)
!               cur_width += gui.char_width;
! #ifdef FEAT_RIGHTLEFT
!           if (CURSOR_BAR_RIGHT)
            {
!               // gui.col points to the left half of the character but
!               // the vertical line needs to be on the right half.
!               // A double-wide horizontal line is also drawn from the
!               // right half in gui_mch_draw_part_cursor().
!               col_off = TRUE;
!               ++gui.col;
            }
  #endif
!       }
!       gui_mch_draw_part_cursor(cur_width, cur_height, cbg);
  #if defined(FEAT_RIGHTLEFT)
!       if (col_off)
!           --gui.col;
  #endif
  
  #ifndef FEAT_GUI_MSWIN            // doesn't seem to work for MSWindows
!       gui.highlight_mask = ScreenAttrs[LineOffset[gui.row] + gui.col];
!       (void)gui_screenchar(LineOffset[gui.row] + gui.col,
!               GUI_MON_TRS_CURSOR | GUI_MON_NOCLEAR,
!               (guicolor_T)0, (guicolor_T)0, 0);
  #endif
      }
+     gui.highlight_mask = old_hl_mask;
  }
  
  #if defined(FEAT_MENU) || defined(PROTO)
***************
*** 2054,2066 ****
      void
  gui_dont_update_cursor(int undraw)
  {
!     if (gui.in_use)
!     {
!       // Undraw the cursor now, we probably can't do it after the change.
!       if (undraw)
!           gui_undraw_cursor();
!       can_update_cursor = FALSE;
!     }
  }
  
      void
--- 2055,2067 ----
      void
  gui_dont_update_cursor(int undraw)
  {
!     if (!gui.in_use)
!       return;
! 
!     // Undraw the cursor now, we probably can't do it after the change.
!     if (undraw)
!       gui_undraw_cursor();
!     can_update_cursor = FALSE;
  }
  
      void
***************
*** 2679,2701 ****
      void
  gui_undraw_cursor(void)
  {
!     if (gui.cursor_is_valid)
!     {
!       // Always redraw the character just before if there is one, because
!       // with some fonts and characters there can be a one pixel overlap.
!       int startcol = gui.cursor_col > 0 ? gui.cursor_col - 1 : gui.cursor_col;
!       int endcol = gui.cursor_col;
  
  #ifdef FEAT_GUI_GTK
!       gui_adjust_undraw_cursor_for_ligatures(&startcol, &endcol);
  #endif
!       gui_redraw_block(gui.cursor_row, startcol,
!                                     gui.cursor_row, endcol, GUI_MON_NOCLEAR);
  
!       // Cursor_is_valid is reset when the cursor is undrawn, also reset it
!       // here in case it wasn't needed to undraw it.
!       gui.cursor_is_valid = FALSE;
!     }
  }
  
      void
--- 2680,2702 ----
      void
  gui_undraw_cursor(void)
  {
!     if (!gui.cursor_is_valid)
!       return;
! 
!     // Always redraw the character just before if there is one, because
!     // with some fonts and characters there can be a one pixel overlap.
!     int startcol = gui.cursor_col > 0 ? gui.cursor_col - 1 : gui.cursor_col;
!     int endcol = gui.cursor_col;
  
  #ifdef FEAT_GUI_GTK
!     gui_adjust_undraw_cursor_for_ligatures(&startcol, &endcol);
  #endif
!     gui_redraw_block(gui.cursor_row, startcol,
!           gui.cursor_row, endcol, GUI_MON_NOCLEAR);
  
!     // Cursor_is_valid is reset when the cursor is undrawn, also reset it
!     // here in case it wasn't needed to undraw it.
!     gui.cursor_is_valid = FALSE;
  }
  
      void
***************
*** 3559,3695 ****
                break;
        }
  
!     if (gui.in_use)
!     {
!       need_set_size = 0;
!       fix_size = FALSE;
  
  #ifdef FEAT_GUI_DARKTHEME
!       if (using_dark_theme != prev_dark_theme)
!       {
!           gui_mch_set_dark_theme(using_dark_theme);
!           prev_dark_theme = using_dark_theme;
!       }
  #endif
  
  #ifdef FEAT_GUI_TABLINE
!       // Update the GUI tab line, it may appear or disappear.  This may
!       // cause the non-GUI tab line to disappear or appear.
!       using_tabline = gui_has_tabline();
!       if (!gui_mch_showing_tabline() != !using_tabline)
!       {
!           // We don't want a resize event change "Rows" here, save and
!           // restore it.  Resizing is handled below.
!           i = Rows;
!           gui_update_tabline();
!           Rows = i;
!           need_set_size |= RESIZE_VERT;
!           if (using_tabline)
!               fix_size = TRUE;
!           if (!gui_use_tabline())
!               redraw_tabline = TRUE;    // may draw non-GUI tab line
!       }
  #endif
  
!       for (i = 0; i < 3; i++)
!       {
!           // The scrollbar needs to be updated when it is shown/unshown and
!           // when switching tab pages.  But the size only changes when it's
!           // shown/unshown.  Thus we need two places to remember whether a
!           // scrollbar is there or not.
!           if (gui.which_scrollbars[i] != prev_which_scrollbars[i]
!                   || gui.which_scrollbars[i]
!                                       != curtab->tp_prev_which_scrollbars[i])
            {
                if (i == SBAR_BOTTOM)
!                   gui_mch_enable_scrollbar(&gui.bottom_sbar,
!                                                    gui.which_scrollbars[i]);
                else
!               {
!                   FOR_ALL_WINDOWS(wp)
!                       gui_do_scrollbar(wp, i, gui.which_scrollbars[i]);
!               }
!               if (gui.which_scrollbars[i] != prev_which_scrollbars[i])
!               {
!                   if (i == SBAR_BOTTOM)
!                       need_set_size |= RESIZE_VERT;
!                   else
!                       need_set_size |= RESIZE_HOR;
!                   if (gui.which_scrollbars[i])
!                       fix_size = TRUE;
!               }
            }
-           curtab->tp_prev_which_scrollbars[i] = gui.which_scrollbars[i];
-           prev_which_scrollbars[i] = gui.which_scrollbars[i];
        }
  
  #ifdef FEAT_MENU
!       if (gui.menu_is_active != prev_menu_is_active)
!       {
!           // We don't want a resize event change "Rows" here, save and
!           // restore it.  Resizing is handled below.
!           i = Rows;
!           gui_mch_enable_menu(gui.menu_is_active);
!           Rows = i;
!           prev_menu_is_active = gui.menu_is_active;
!           need_set_size |= RESIZE_VERT;
!           if (gui.menu_is_active)
!               fix_size = TRUE;
!       }
  #endif
  
  #ifdef FEAT_TOOLBAR
!       if (using_toolbar != prev_toolbar)
!       {
!           gui_mch_show_toolbar(using_toolbar);
!           prev_toolbar = using_toolbar;
!           need_set_size |= RESIZE_VERT;
!           if (using_toolbar)
!               fix_size = TRUE;
!       }
  #endif
  #if defined(FEAT_MENU) && !(defined(MSWIN) && !defined(FEAT_TEAROFF))
!       if (using_tearoff != prev_tearoff)
!       {
!           gui_mch_toggle_tearoffs(using_tearoff);
!           prev_tearoff = using_tearoff;
!       }
  #endif
!       if (need_set_size != 0)
!       {
  #ifdef FEAT_GUI_GTK
!           long    prev_Columns = Columns;
!           long    prev_Rows = Rows;
  #endif
!           // Adjust the size of the window to make the text area keep the
!           // same size and to avoid that part of our window is off-screen
!           // and a scrollbar can't be used, for example.
!           gui_set_shellsize(FALSE, fix_size, need_set_size);
  
  #ifdef FEAT_GUI_GTK
!           // GTK has the annoying habit of sending us resize events when
!           // changing the window size ourselves.  This mostly happens when
!           // waiting for a character to arrive, quite unpredictably, and may
!           // change Columns and Rows when we don't want it.  Wait for a
!           // character here to avoid this effect.
!           // If you remove this, please test this command for resizing
!           // effects (with optional left scrollbar): ":vsp|q|vsp|q|vsp|q".
!           // Don't do this while starting up though.
!           // Don't change Rows when adding menu/toolbar/tabline.
!           // Don't change Columns when adding vertical toolbar.
!           if (!gui.starting && need_set_size != (RESIZE_VERT | RESIZE_HOR))
!               (void)char_avail();
!           if ((need_set_size & RESIZE_VERT) == 0)
!               Rows = prev_Rows;
!           if ((need_set_size & RESIZE_HOR) == 0)
!               Columns = prev_Columns;
! #endif
!       }
!       // When the console tabline appears or disappears the window positions
!       // change.
!       if (firstwin->w_winrow != tabline_height())
!           shell_new_rows();   // recompute window positions and heights
!     }
  }
  
  #if defined(FEAT_GUI_TABLINE) || defined(PROTO)
--- 3560,3696 ----
                break;
        }
  
!     if (!gui.in_use)
!       return;
! 
!     need_set_size = 0;
!     fix_size = FALSE;
  
  #ifdef FEAT_GUI_DARKTHEME
!     if (using_dark_theme != prev_dark_theme)
!     {
!       gui_mch_set_dark_theme(using_dark_theme);
!       prev_dark_theme = using_dark_theme;
!     }
  #endif
  
  #ifdef FEAT_GUI_TABLINE
!     // Update the GUI tab line, it may appear or disappear.  This may
!     // cause the non-GUI tab line to disappear or appear.
!     using_tabline = gui_has_tabline();
!     if (!gui_mch_showing_tabline() != !using_tabline)
!     {
!       // We don't want a resize event change "Rows" here, save and
!       // restore it.  Resizing is handled below.
!       i = Rows;
!       gui_update_tabline();
!       Rows = i;
!       need_set_size |= RESIZE_VERT;
!       if (using_tabline)
!           fix_size = TRUE;
!       if (!gui_use_tabline())
!           redraw_tabline = TRUE;    // may draw non-GUI tab line
!     }
  #endif
  
!     for (i = 0; i < 3; i++)
!     {
!       // The scrollbar needs to be updated when it is shown/unshown and
!       // when switching tab pages.  But the size only changes when it's
!       // shown/unshown.  Thus we need two places to remember whether a
!       // scrollbar is there or not.
!       if (gui.which_scrollbars[i] != prev_which_scrollbars[i]
!               || gui.which_scrollbars[i]
!               != curtab->tp_prev_which_scrollbars[i])
!       {
!           if (i == SBAR_BOTTOM)
!               gui_mch_enable_scrollbar(&gui.bottom_sbar,
!                       gui.which_scrollbars[i]);
!           else
!           {
!               FOR_ALL_WINDOWS(wp)
!                   gui_do_scrollbar(wp, i, gui.which_scrollbars[i]);
!           }
!           if (gui.which_scrollbars[i] != prev_which_scrollbars[i])
            {
                if (i == SBAR_BOTTOM)
!                   need_set_size |= RESIZE_VERT;
                else
!                   need_set_size |= RESIZE_HOR;
!               if (gui.which_scrollbars[i])
!                   fix_size = TRUE;
            }
        }
+       curtab->tp_prev_which_scrollbars[i] = gui.which_scrollbars[i];
+       prev_which_scrollbars[i] = gui.which_scrollbars[i];
+     }
  
  #ifdef FEAT_MENU
!     if (gui.menu_is_active != prev_menu_is_active)
!     {
!       // We don't want a resize event change "Rows" here, save and
!       // restore it.  Resizing is handled below.
!       i = Rows;
!       gui_mch_enable_menu(gui.menu_is_active);
!       Rows = i;
!       prev_menu_is_active = gui.menu_is_active;
!       need_set_size |= RESIZE_VERT;
!       if (gui.menu_is_active)
!           fix_size = TRUE;
!     }
  #endif
  
  #ifdef FEAT_TOOLBAR
!     if (using_toolbar != prev_toolbar)
!     {
!       gui_mch_show_toolbar(using_toolbar);
!       prev_toolbar = using_toolbar;
!       need_set_size |= RESIZE_VERT;
!       if (using_toolbar)
!           fix_size = TRUE;
!     }
  #endif
  #if defined(FEAT_MENU) && !(defined(MSWIN) && !defined(FEAT_TEAROFF))
!     if (using_tearoff != prev_tearoff)
!     {
!       gui_mch_toggle_tearoffs(using_tearoff);
!       prev_tearoff = using_tearoff;
!     }
  #endif
!     if (need_set_size != 0)
!     {
  #ifdef FEAT_GUI_GTK
!       long    prev_Columns = Columns;
!       long    prev_Rows = Rows;
  #endif
!       // Adjust the size of the window to make the text area keep the
!       // same size and to avoid that part of our window is off-screen
!       // and a scrollbar can't be used, for example.
!       gui_set_shellsize(FALSE, fix_size, need_set_size);
  
  #ifdef FEAT_GUI_GTK
!       // GTK has the annoying habit of sending us resize events when
!       // changing the window size ourselves.  This mostly happens when
!       // waiting for a character to arrive, quite unpredictably, and may
!       // change Columns and Rows when we don't want it.  Wait for a
!       // character here to avoid this effect.
!       // If you remove this, please test this command for resizing
!       // effects (with optional left scrollbar): ":vsp|q|vsp|q|vsp|q".
!       // Don't do this while starting up though.
!       // Don't change Rows when adding menu/toolbar/tabline.
!       // Don't change Columns when adding vertical toolbar.
!       if (!gui.starting && need_set_size != (RESIZE_VERT | RESIZE_HOR))
!           (void)char_avail();
!       if ((need_set_size & RESIZE_VERT) == 0)
!           Rows = prev_Rows;
!       if ((need_set_size & RESIZE_HOR) == 0)
!           Columns = prev_Columns;
! #endif
!     }
!     // When the console tabline appears or disappears the window positions
!     // change.
!     if (firstwin->w_winrow != tabline_height())
!       shell_new_rows();       // recompute window positions and heights
  }
  
  #if defined(FEAT_GUI_TABLINE) || defined(PROTO)
***************
*** 4768,4774 ****
            return;
  
        /*
!        * format a mouse click on status line input
         * ala gui_send_mouse_event(0, x, y, 0, 0);
         * Trick: Use a column number -1, so that get_pseudo_mouse_code() will
         * generate a K_LEFTMOUSE_NM key code.
--- 4769,4775 ----
            return;
  
        /*
!        * Format a mouse click on status line input,
         * ala gui_send_mouse_event(0, x, y, 0, 0);
         * Trick: Use a column number -1, so that get_pseudo_mouse_code() will
         * generate a K_LEFTMOUSE_NM key code.
***************
*** 4852,4864 ****
      need_mouse_correct = FALSE;
  
      wp = gui_mouse_window(IGNORE_POPUP);
!     if (wp != curwin && wp != NULL)   // If in other than current window
!     {
!       validate_cline_row();
!       gui_mch_setmouse((int)W_ENDCOL(curwin) * gui.char_width - 3,
!               (W_WINROW(curwin) + curwin->w_wrow) * gui.char_height
!                                                    + (gui.char_height) / 2);
!     }
  }
  
  /*
--- 4853,4866 ----
      need_mouse_correct = FALSE;
  
      wp = gui_mouse_window(IGNORE_POPUP);
!     if (wp == curwin || wp == NULL)
!       return;
! 
!     // If in other than current window
!     validate_cline_row();
!     gui_mch_setmouse((int)W_ENDCOL(curwin) * gui.char_width - 3,
!           (W_WINROW(curwin) + curwin->w_wrow) * gui.char_height
!           + (gui.char_height) / 2);
  }
  
  /*
***************
*** 5014,5035 ****
      char_u    *p;
  
      if (isatty(2))
-       fflush(stderr);
-     else if (error_ga.ga_data != NULL)
      {
!       // avoid putting up a message box with blanks only
!       for (p = (char_u *)error_ga.ga_data; *p != NUL; ++p)
!           if (!isspace(*p))
!           {
!               // Truncate a very long message, it will go off-screen.
!               if (STRLEN(p) > 2000)
!                   STRCPY(p + 2000 - 14, "...(truncated)");
!               (void)do_dialog(VIM_ERROR, (char_u *)_("Error"),
!                                      p, (char_u *)_("&Ok"), 1, NULL, FALSE);
!               break;
!           }
!       ga_clear(&error_ga);
      }
  }
  #endif
  
--- 5016,5041 ----
      char_u    *p;
  
      if (isatty(2))
      {
!       fflush(stderr);
!       return;
      }
+ 
+     if (error_ga.ga_data == NULL)
+       return;
+ 
+     // avoid putting up a message box with blanks only
+     for (p = (char_u *)error_ga.ga_data; *p != NUL; ++p)
+       if (!isspace(*p))
+       {
+           // Truncate a very long message, it will go off-screen.
+           if (STRLEN(p) > 2000)
+               STRCPY(p + 2000 - 14, "...(truncated)");
+           (void)do_dialog(VIM_ERROR, (char_u *)_("Error"),
+                   p, (char_u *)_("&Ok"), 1, NULL, FALSE);
+           break;
+       }
+     ga_clear(&error_ga);
  }
  #endif
  
***************
*** 5339,5350 ****
      int               col = X_2_COL(x);
      win_T     *wp;
  
!     if (row >= 0 && col >= 0)
!     {
!       wp = mouse_find_win(&row, &col, FAIL_POPUP);
!       if (wp != NULL && wp != curwin)
!           win_goto(wp);
!     }
  }
  
  /*
--- 5345,5356 ----
      int               col = X_2_COL(x);
      win_T     *wp;
  
!     if (row < 0 || col < 0)
!       return;
! 
!     wp = mouse_find_win(&row, &col, FAIL_POPUP);
!     if (wp != NULL && wp != curwin)
!       win_goto(wp);
  }
  
  /*
*** ../vim-9.0.1157/src/gui_beval.c     2022-04-03 17:19:01.000000000 +0100
--- src/gui_beval.c     2023-01-08 13:38:57.105602496 +0000
***************
*** 373,412 ****
  
      distance = ABS(x - beval->x) + ABS(y - beval->y);
  
!     if (distance > 4)
      {
!       /*
!        * Moved out of the balloon location: cancel it.
!        * Remember button state
!        */
!       beval->state = state;
!       cancelBalloon(beval);
  
!       // Mouse buttons are pressed - no balloon now
!       if (!(state & ((int)GDK_BUTTON1_MASK | (int)GDK_BUTTON2_MASK
!                                                   | (int)GDK_BUTTON3_MASK)))
        {
!           beval->x = x;
!           beval->y = y;
! 
!           if (state & (int)GDK_MOD1_MASK)
!           {
!               /*
!                * Alt is pressed -- enter super-evaluate-mode,
!                * where there is no time delay
!                */
!               if (beval->msgCB != NULL)
!               {
!                   beval->showState = ShS_PENDING;
!                   (*beval->msgCB)(beval, state);
!               }
!           }
!           else
            {
!               beval->timerID = g_timeout_add((guint)p_bdlay,
!                                              &timeout_cb, beval);
            }
        }
      }
  }
  
--- 373,412 ----
  
      distance = ABS(x - beval->x) + ABS(y - beval->y);
  
!     if (distance <= 4)
!       return;
! 
!     /*
!      * Moved out of the balloon location: cancel it.
!      * Remember button state
!      */
!     beval->state = state;
!     cancelBalloon(beval);
! 
!     // Mouse buttons are pressed - no balloon now
!     if (!(state & ((int)GDK_BUTTON1_MASK | (int)GDK_BUTTON2_MASK
!                   | (int)GDK_BUTTON3_MASK)))
      {
!       beval->x = x;
!       beval->y = y;
  
!       if (state & (int)GDK_MOD1_MASK)
        {
!           /*
!            * Alt is pressed -- enter super-evaluate-mode,
!            * where there is no time delay
!            */
!           if (beval->msgCB != NULL)
            {
!               beval->showState = ShS_PENDING;
!               (*beval->msgCB)(beval, state);
            }
        }
+       else
+       {
+           beval->timerID = g_timeout_add((guint)p_bdlay,
+                   &timeout_cb, beval);
+       }
      }
  }
  
***************
*** 698,714 ****
      static void
  requestBalloon(BalloonEval *beval)
  {
!     if (beval->showState != ShS_PENDING)
      {
!       // Determine the beval to display
!       if (beval->msgCB != NULL)
!       {
!           beval->showState = ShS_PENDING;
!           (*beval->msgCB)(beval, beval->state);
!       }
!       else if (beval->msg != NULL)
!           drawBalloon(beval);
      }
  }
  
  #ifdef FEAT_GUI_GTK
--- 698,714 ----
      static void
  requestBalloon(BalloonEval *beval)
  {
!     if (beval->showState == ShS_PENDING)
!       return;
! 
!     // Determine the beval to display
!     if (beval->msgCB != NULL)
      {
!       beval->showState = ShS_PENDING;
!       (*beval->msgCB)(beval, beval->state);
      }
+     else if (beval->msg != NULL)
+       drawBalloon(beval);
  }
  
  #ifdef FEAT_GUI_GTK
***************
*** 900,984 ****
      static void
  drawBalloon(BalloonEval *beval)
  {
!     if (beval->msg != NULL)
!     {
!       GtkRequisition  requisition;
!       int             screen_w;
!       int             screen_h;
!       int             screen_x;
!       int             screen_y;
!       int             x;
!       int             y;
!       int             x_offset = EVAL_OFFSET_X;
!       int             y_offset = EVAL_OFFSET_Y;
!       PangoLayout     *layout;
  
  # if !GTK_CHECK_VERSION(3,22,2)
!       GdkScreen       *screen;
  
!       screen = gtk_widget_get_screen(beval->target);
!       gtk_window_set_screen(GTK_WINDOW(beval->balloonShell), screen);
  # endif
!       gui_gtk_get_screen_geom_of_win(beval->target, 0, 0,
!                                   &screen_x, &screen_y, &screen_w, &screen_h);
  # if !GTK_CHECK_VERSION(3,0,0)
!       gtk_widget_ensure_style(beval->balloonShell);
!       gtk_widget_ensure_style(beval->balloonLabel);
  # endif
  
!       set_printable_label_text(GTK_LABEL(beval->balloonLabel), beval->msg);
!       /*
!        * Dirty trick:  Enable wrapping mode on the label's layout behind its
!        * back.  This way GtkLabel won't try to constrain the wrap width to a
!        * builtin maximum value of about 65 Latin characters.
!        */
!       layout = gtk_label_get_layout(GTK_LABEL(beval->balloonLabel));
  # ifdef PANGO_WRAP_WORD_CHAR
!       pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
  # else
!       pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
  # endif
!       pango_layout_set_width(layout,
!               // try to come up with some reasonable width
!               PANGO_SCALE * CLAMP(gui.num_cols * gui.char_width,
!                                   screen_w / 2,
!                                   MAX(20, screen_w - 20)));
  
!       // Calculate the balloon's width and height.
  # if GTK_CHECK_VERSION(3,0,0)
!       gtk_widget_get_preferred_size(beval->balloonShell, &requisition, NULL);
  # else
!       gtk_widget_size_request(beval->balloonShell, &requisition);
  # endif
  
!       // Compute position of the balloon area
!       gdk_window_get_origin(gtk_widget_get_window(beval->target), &x, &y);
!       x += beval->x;
!       y += beval->y;
! 
!       // Get out of the way of the mouse pointer
!       if (x + x_offset + requisition.width > screen_x + screen_w)
!           y_offset += 15;
!       if (y + y_offset + requisition.height > screen_y + screen_h)
!           y_offset = -requisition.height - EVAL_OFFSET_Y;
! 
!       // Sanitize values
!       x = CLAMP(x + x_offset, 0,
!                           MAX(0, screen_x + screen_w - requisition.width));
!       y = CLAMP(y + y_offset, 0,
!                           MAX(0, screen_y + screen_h - requisition.height));
  
!       // Show the balloon
  # if GTK_CHECK_VERSION(3,0,0)
!       gtk_window_move(GTK_WINDOW(beval->balloonShell), x, y);
  # else
!       gtk_widget_set_uposition(beval->balloonShell, x, y);
  # endif
!       gtk_widget_show(beval->balloonShell);
  
!       beval->showState = ShS_SHOWING;
!       gui_mch_update();
!     }
  }
  
  /*
--- 900,984 ----
      static void
  drawBalloon(BalloonEval *beval)
  {
!     if (beval->msg == NULL)
!       return;
! 
!     GtkRequisition    requisition;
!     int               screen_w;
!     int               screen_h;
!     int               screen_x;
!     int               screen_y;
!     int               x;
!     int               y;
!     int               x_offset = EVAL_OFFSET_X;
!     int               y_offset = EVAL_OFFSET_Y;
!     PangoLayout       *layout;
  
  # if !GTK_CHECK_VERSION(3,22,2)
!     GdkScreen *screen;
  
!     screen = gtk_widget_get_screen(beval->target);
!     gtk_window_set_screen(GTK_WINDOW(beval->balloonShell), screen);
  # endif
!     gui_gtk_get_screen_geom_of_win(beval->target, 0, 0,
!           &screen_x, &screen_y, &screen_w, &screen_h);
  # if !GTK_CHECK_VERSION(3,0,0)
!     gtk_widget_ensure_style(beval->balloonShell);
!     gtk_widget_ensure_style(beval->balloonLabel);
  # endif
  
!     set_printable_label_text(GTK_LABEL(beval->balloonLabel), beval->msg);
!     /*
!      * Dirty trick:  Enable wrapping mode on the label's layout behind its
!      * back.  This way GtkLabel won't try to constrain the wrap width to a
!      * builtin maximum value of about 65 Latin characters.
!      */
!     layout = gtk_label_get_layout(GTK_LABEL(beval->balloonLabel));
  # ifdef PANGO_WRAP_WORD_CHAR
!     pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
  # else
!     pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
  # endif
!     pango_layout_set_width(layout,
!           // try to come up with some reasonable width
!           PANGO_SCALE * CLAMP(gui.num_cols * gui.char_width,
!               screen_w / 2,
!               MAX(20, screen_w - 20)));
  
!     // Calculate the balloon's width and height.
  # if GTK_CHECK_VERSION(3,0,0)
!     gtk_widget_get_preferred_size(beval->balloonShell, &requisition, NULL);
  # else
!     gtk_widget_size_request(beval->balloonShell, &requisition);
  # endif
  
!     // Compute position of the balloon area
!     gdk_window_get_origin(gtk_widget_get_window(beval->target), &x, &y);
!     x += beval->x;
!     y += beval->y;
! 
!     // Get out of the way of the mouse pointer
!     if (x + x_offset + requisition.width > screen_x + screen_w)
!       y_offset += 15;
!     if (y + y_offset + requisition.height > screen_y + screen_h)
!       y_offset = -requisition.height - EVAL_OFFSET_Y;
! 
!     // Sanitize values
!     x = CLAMP(x + x_offset, 0,
!           MAX(0, screen_x + screen_w - requisition.width));
!     y = CLAMP(y + y_offset, 0,
!           MAX(0, screen_y + screen_h - requisition.height));
  
!     // Show the balloon
  # if GTK_CHECK_VERSION(3,0,0)
!     gtk_window_move(GTK_WINDOW(beval->balloonShell), x, y);
  # else
!     gtk_widget_set_uposition(beval->balloonShell, x, y);
  # endif
!     gtk_widget_show(beval->balloonShell);
  
!     beval->showState = ShS_SHOWING;
!     gui_mch_update();
  }
  
  /*
***************
*** 1060,1124 ****
      Position tx;
      Position ty;
  
!     if (beval->msg != NULL)
!     {
!       XmString s;
!       // Show the Balloon
  
!       // Calculate the label's width and height
  
!       // For the callback function we parse NL characters to create a
!       // multi-line label.  This doesn't work for all languages, but
!       // XmStringCreateLocalized() doesn't do multi-line labels...
!       if (beval->msgCB != NULL)
!           s = XmStringCreateLtoR((char *)beval->msg, XmFONTLIST_DEFAULT_TAG);
!       else
!           s = XmStringCreateLocalized((char *)beval->msg);
!       {
!           XmFontList fl;
  
!           fl = gui_motif_fontset2fontlist(&gui.tooltip_fontset);
!           if (fl == NULL)
!           {
!               XmStringFree(s);
!               return;
!           }
!           XmStringExtent(fl, s, &w, &h);
!           XmFontListFree(fl);
!       }
!       w += gui.border_offset << 1;
!       h += gui.border_offset << 1;
!       XtVaSetValues(beval->balloonLabel, XmNlabelString, s, NULL);
!       XmStringFree(s);
! 
!       // Compute position of the balloon area
!       tx = beval->x_root + EVAL_OFFSET_X;
!       ty = beval->y_root + EVAL_OFFSET_Y;
!       if ((tx + w) > beval->screen_width)
!           tx = beval->screen_width - w;
!       if ((ty + h) > beval->screen_height)
!           ty = beval->screen_height - h;
!       XtVaSetValues(beval->balloonShell,
!               XmNx, tx,
!               XmNy, ty,
!               NULL);
!       // Set tooltip colors
!       {
!           Arg args[2];
  
!           args[0].name = XmNbackground;
!           args[0].value = gui.tooltip_bg_pixel;
!           args[1].name = XmNforeground;
!           args[1].value = gui.tooltip_fg_pixel;
!           XtSetValues(beval->balloonLabel, &args[0], XtNumber(args));
        }
  
!       XtPopup(beval->balloonShell, XtGrabNone);
  
!       beval->showState = ShS_SHOWING;
  
!       current_beval = beval;
!     }
  }
  
  /*
--- 1060,1124 ----
      Position tx;
      Position ty;
  
!     if (beval->msg == NULL)
!       return;
  
!     XmString s;
!     // Show the Balloon
  
!     // Calculate the label's width and height
  
!     // For the callback function we parse NL characters to create a
!     // multi-line label.  This doesn't work for all languages, but
!     // XmStringCreateLocalized() doesn't do multi-line labels...
!     if (beval->msgCB != NULL)
!       s = XmStringCreateLtoR((char *)beval->msg, XmFONTLIST_DEFAULT_TAG);
!     else
!       s = XmStringCreateLocalized((char *)beval->msg);
!     {
!       XmFontList fl;
  
!       fl = gui_motif_fontset2fontlist(&gui.tooltip_fontset);
!       if (fl == NULL)
!       {
!           XmStringFree(s);
!           return;
        }
+       XmStringExtent(fl, s, &w, &h);
+       XmFontListFree(fl);
+     }
+     w += gui.border_offset << 1;
+     h += gui.border_offset << 1;
+     XtVaSetValues(beval->balloonLabel, XmNlabelString, s, NULL);
+     XmStringFree(s);
+ 
+     // Compute position of the balloon area
+     tx = beval->x_root + EVAL_OFFSET_X;
+     ty = beval->y_root + EVAL_OFFSET_Y;
+     if ((tx + w) > beval->screen_width)
+       tx = beval->screen_width - w;
+     if ((ty + h) > beval->screen_height)
+       ty = beval->screen_height - h;
+     XtVaSetValues(beval->balloonShell,
+           XmNx, tx,
+           XmNy, ty,
+           NULL);
+     // Set tooltip colors
+     {
+       Arg args[2];
+ 
+       args[0].name = XmNbackground;
+       args[0].value = gui.tooltip_bg_pixel;
+       args[1].name = XmNforeground;
+       args[1].value = gui.tooltip_fg_pixel;
+       XtSetValues(beval->balloonLabel, &args[0], XtNumber(args));
+     }
  
!     XtPopup(beval->balloonShell, XtGrabNone);
  
!     beval->showState = ShS_SHOWING;
  
!     current_beval = beval;
  }
  
  /*
***************
*** 1161,1178 ****
      beval->balloonShell = XtAppCreateShell("balloonEval", "BalloonEval",
                    overrideShellWidgetClass, gui.dpy, args, n);
  
!     {
!       XmFontList fl;
  
!       n = 0;
!       fl = gui_motif_fontset2fontlist(&gui.tooltip_fontset);
!       XtSetArg(args[n], XmNforeground, gui.tooltip_fg_pixel); n++;
!       XtSetArg(args[n], XmNbackground, gui.tooltip_bg_pixel); n++;
!       XtSetArg(args[n], XmNfontList, fl); n++;
!       XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
!       beval->balloonLabel = XtCreateManagedWidget("balloonLabel",
!                       xmLabelWidgetClass, beval->balloonShell, args, n);
!     }
  }
  
  #endif // !FEAT_GUI_GTK
--- 1161,1176 ----
      beval->balloonShell = XtAppCreateShell("balloonEval", "BalloonEval",
                    overrideShellWidgetClass, gui.dpy, args, n);
  
!     XmFontList fl;
  
!     n = 0;
!     fl = gui_motif_fontset2fontlist(&gui.tooltip_fontset);
!     XtSetArg(args[n], XmNforeground, gui.tooltip_fg_pixel); n++;
!     XtSetArg(args[n], XmNbackground, gui.tooltip_bg_pixel); n++;
!     XtSetArg(args[n], XmNfontList, fl); n++;
!     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
!     beval->balloonLabel = XtCreateManagedWidget("balloonLabel",
!           xmLabelWidgetClass, beval->balloonShell, args, n);
  }
  
  #endif // !FEAT_GUI_GTK
*** ../vim-9.0.1157/src/gui_gtk.c       2022-05-07 18:08:58.000000000 +0100
--- src/gui_gtk.c       2023-01-08 13:38:57.105602496 +0000
***************
*** 924,945 ****
      void
  gui_mch_menu_set_tip(vimmenu_T *menu)
  {
!     if (menu->id != NULL && menu->parent != NULL && gui.toolbar != NULL)
!     {
!       char_u *tooltip;
  
!       tooltip = CONVERT_TO_UTF8(menu->strings[MENU_INDEX_TIP]);
!       if (tooltip != NULL && utf_valid_string(tooltip, NULL))
  # if GTK_CHECK_VERSION(3,0,0)
!           // Only set the tooltip when it's valid utf-8.
!           gtk_widget_set_tooltip_text(menu->id, (const gchar *)tooltip);
  # else
!           // Only set the tooltip when it's valid utf-8.
!           gtk_tooltips_set_tip(GTK_TOOLBAR(gui.toolbar)->tooltips,
!                                menu->id, (const char *)tooltip, NULL);
  # endif
!       CONVERT_TO_UTF8_FREE(tooltip);
!     }
  }
  #endif // FEAT_TOOLBAR
  
--- 924,945 ----
      void
  gui_mch_menu_set_tip(vimmenu_T *menu)
  {
!     if (menu->id == NULL || menu->parent == NULL || gui.toolbar == NULL)
!       return;
! 
!     char_u *tooltip;
  
!     tooltip = CONVERT_TO_UTF8(menu->strings[MENU_INDEX_TIP]);
!     if (tooltip != NULL && utf_valid_string(tooltip, NULL))
  # if GTK_CHECK_VERSION(3,0,0)
!       // Only set the tooltip when it's valid utf-8.
!       gtk_widget_set_tooltip_text(menu->id, (const gchar *)tooltip);
  # else
!     // Only set the tooltip when it's valid utf-8.
!     gtk_tooltips_set_tip(GTK_TOOLBAR(gui.toolbar)->tooltips,
!           menu->id, (const char *)tooltip, NULL);
  # endif
!     CONVERT_TO_UTF8_FREE(tooltip);
  }
  #endif // FEAT_TOOLBAR
  
***************
*** 1007,1040 ****
      void
  gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max)
  {
!     if (sb->id != NULL)
!     {
!       GtkAdjustment *adjustment;
  
!       // ignore events triggered by moving the thumb (happens in GTK 3)
!       ++hold_gui_events;
  
!       adjustment = gtk_range_get_adjustment(GTK_RANGE(sb->id));
  
!       gtk_adjustment_set_lower(adjustment, 0.0);
!       gtk_adjustment_set_value(adjustment, val);
!       gtk_adjustment_set_upper(adjustment, max + 1);
!       gtk_adjustment_set_page_size(adjustment, size);
!       gtk_adjustment_set_page_increment(adjustment,
!                                         size < 3L ? 1L : size - 2L);
!       gtk_adjustment_set_step_increment(adjustment, 1.0);
  
!       g_signal_handler_block(G_OBJECT(adjustment), (gulong)sb->handler_id);
  
!       --hold_gui_events;
  
  #if !GTK_CHECK_VERSION(3,18,0)
!       gtk_adjustment_changed(adjustment);
  #endif
  
!       g_signal_handler_unblock(G_OBJECT(adjustment),
!                                                     (gulong)sb->handler_id);
!     }
  }
  
      void
--- 1007,1040 ----
      void
  gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max)
  {
!     if (sb->id == NULL)
!       return;
  
!     GtkAdjustment *adjustment;
  
!     // ignore events triggered by moving the thumb (happens in GTK 3)
!     ++hold_gui_events;
  
!     adjustment = gtk_range_get_adjustment(GTK_RANGE(sb->id));
  
!     gtk_adjustment_set_lower(adjustment, 0.0);
!     gtk_adjustment_set_value(adjustment, val);
!     gtk_adjustment_set_upper(adjustment, max + 1);
!     gtk_adjustment_set_page_size(adjustment, size);
!     gtk_adjustment_set_page_increment(adjustment,
!           size < 3L ? 1L : size - 2L);
!     gtk_adjustment_set_step_increment(adjustment, 1.0);
  
!     g_signal_handler_block(G_OBJECT(adjustment), (gulong)sb->handler_id);
! 
!     --hold_gui_events;
  
  #if !GTK_CHECK_VERSION(3,18,0)
!     gtk_adjustment_changed(adjustment);
  #endif
  
!     g_signal_handler_unblock(G_OBJECT(adjustment),
!           (gulong)sb->handler_id);
  }
  
      void
***************
*** 1157,1177 ****
        sb->id = gtk_vscrollbar_new(NULL);
  #endif
  
!     if (sb->id != NULL)
!     {
!       GtkAdjustment *adjustment;
  
!       gtk_widget_set_can_focus(sb->id, FALSE);
!       gui_gtk_form_put(GTK_FORM(gui.formwin), sb->id, 0, 0);
  
!       adjustment = gtk_range_get_adjustment(GTK_RANGE(sb->id));
  
!       sb->handler_id = g_signal_connect(
!                            G_OBJECT(adjustment), "value-changed",
!                            G_CALLBACK(adjustment_value_changed),
!                            GINT_TO_POINTER(sb->ident));
!       gui_mch_update();
!     }
  }
  
      void
--- 1157,1177 ----
        sb->id = gtk_vscrollbar_new(NULL);
  #endif
  
!     if (sb->id == NULL)
!       return;
  
!     GtkAdjustment *adjustment;
  
!     gtk_widget_set_can_focus(sb->id, FALSE);
!     gui_gtk_form_put(GTK_FORM(gui.formwin), sb->id, 0, 0);
  
!     adjustment = gtk_range_get_adjustment(GTK_RANGE(sb->id));
! 
!     sb->handler_id = g_signal_connect(
!           G_OBJECT(adjustment), "value-changed",
!           G_CALLBACK(adjustment_value_changed),
!           GINT_TO_POINTER(sb->ident));
!     gui_mch_update();
  }
  
      void
***************
*** 1994,2052 ****
      popup_mouse_pos = mouse_pos;
  
      menu = gui_find_menu(path_name);
  
-     if (menu != NULL && menu->submenu_id != NULL)
-     {
  # if GTK_CHECK_VERSION(3,22,2)
!       GdkWindow * const win = gtk_widget_get_window(gui.drawarea);
!       GdkEventButton trigger;
  
!       // A pseudo event to have gtk_menu_popup_at_*() functions work. Since
!       // the position where the menu pops up is automatically adjusted by
!       // the functions, none of the fields x, y, x_root and y_root has to be
!       // set to a specific value here; therefore, they are set to zero for
!       // convenience.
!       trigger.type       = GDK_BUTTON_PRESS;
!       trigger.window     = win;
!       trigger.send_event = FALSE;
!       trigger.time       = GDK_CURRENT_TIME;
!       trigger.x          = 0.0;
!       trigger.y          = 0.0;
!       trigger.axes       = NULL;
!       trigger.state      = 0;
!       trigger.button     = 0;
!       trigger.device     = NULL;
!       trigger.x_root     = 0.0;
!       trigger.y_root     = 0.0;
  
!       if (mouse_pos)
!           gtk_menu_popup_at_pointer(GTK_MENU(menu->submenu_id),
!                                     (GdkEvent *)&trigger);
!       else
!       {
!           gint origin_x, origin_y;
!           GdkRectangle rect = { 0, 0, 0, 0 };
  
!           gdk_window_get_origin(win, &origin_x, &origin_y);
!           popup_menu_position_func(NULL, &rect.x, &rect.y, NULL, NULL);
  
!           rect.x -= origin_x;
!           rect.y -= origin_y;
  
!           gtk_menu_popup_at_rect(GTK_MENU(menu->submenu_id),
!                                  win,
!                                  &rect,
!                                  GDK_GRAVITY_SOUTH_EAST,
!                                  GDK_GRAVITY_NORTH_WEST,
!                                  (GdkEvent *)&trigger);
!       }
  # else
!       gtk_menu_popup(GTK_MENU(menu->submenu_id),
!                      NULL, NULL,
!                      &popup_menu_position_func, NULL,
!                      0U, (guint32)GDK_CURRENT_TIME);
  # endif
-     }
  }
  
  #endif // FEAT_MENU
--- 1994,2051 ----
      popup_mouse_pos = mouse_pos;
  
      menu = gui_find_menu(path_name);
+     if (menu == NULL || menu->submenu_id == NULL)
+       return;
  
  # if GTK_CHECK_VERSION(3,22,2)
!     GdkWindow * const win = gtk_widget_get_window(gui.drawarea);
!     GdkEventButton trigger;
  
!     // A pseudo event to have gtk_menu_popup_at_*() functions work. Since
!     // the position where the menu pops up is automatically adjusted by
!     // the functions, none of the fields x, y, x_root and y_root has to be
!     // set to a specific value here; therefore, they are set to zero for
!     // convenience.
!     trigger.type       = GDK_BUTTON_PRESS;
!     trigger.window     = win;
!     trigger.send_event = FALSE;
!     trigger.time       = GDK_CURRENT_TIME;
!     trigger.x    = 0.0;
!     trigger.y    = 0.0;
!     trigger.axes       = NULL;
!     trigger.state      = 0;
!     trigger.button     = 0;
!     trigger.device     = NULL;
!     trigger.x_root     = 0.0;
!     trigger.y_root     = 0.0;
  
!     if (mouse_pos)
!       gtk_menu_popup_at_pointer(GTK_MENU(menu->submenu_id),
!               (GdkEvent *)&trigger);
!     else
!     {
!       gint origin_x, origin_y;
!       GdkRectangle rect = { 0, 0, 0, 0 };
  
!       gdk_window_get_origin(win, &origin_x, &origin_y);
!       popup_menu_position_func(NULL, &rect.x, &rect.y, NULL, NULL);
  
!       rect.x -= origin_x;
!       rect.y -= origin_y;
  
!       gtk_menu_popup_at_rect(GTK_MENU(menu->submenu_id),
!               win,
!               &rect,
!               GDK_GRAVITY_SOUTH_EAST,
!               GDK_GRAVITY_NORTH_WEST,
!               (GdkEvent *)&trigger);
!     }
  # else
!     gtk_menu_popup(GTK_MENU(menu->submenu_id),
!           NULL, NULL,
!           &popup_menu_position_func, NULL,
!           0U, (guint32)GDK_CURRENT_TIME);
  # endif
  }
  
  #endif // FEAT_MENU
*** ../vim-9.0.1157/src/gui_gtk_f.c     2021-10-17 11:27:49.000000000 +0100
--- src/gui_gtk_f.c     2023-01-08 13:38:57.105602496 +0000
***************
*** 188,200 ****
  {
      g_return_if_fail(GTK_IS_FORM(form));
  
!     if (form->freeze_count)
      {
!       if (!(--form->freeze_count))
!       {
!           form_position_children(form);
!           gtk_widget_queue_draw(GTK_WIDGET(form));
!       }
      }
  }
  
--- 188,200 ----
  {
      g_return_if_fail(GTK_IS_FORM(form));
  
!     if (!form->freeze_count)
!       return;
! 
!     if (!(--form->freeze_count))
      {
!       form_position_children(form);
!       gtk_widget_queue_draw(GTK_WIDGET(form));
      }
  }
  
***************
*** 610,641 ****
        tmp_list = tmp_list->next;
      }
  
!     if (tmp_list)
!     {
  #if GTK_CHECK_VERSION(3,0,0)
!       const gboolean was_visible = gtk_widget_get_visible(widget);
  #endif
!       if (child->window)
!       {
!           g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget),
!                   FUNC2GENERIC(&form_child_map), child);
!           g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget),
!                   FUNC2GENERIC(&form_child_unmap), child);
  
!           // FIXME: This will cause problems for reparenting NO_WINDOW
!           // widgets out of a GtkForm
!           gdk_window_set_user_data(child->window, NULL);
!           gdk_window_destroy(child->window);
!       }
!       gtk_widget_unparent(widget);
  #if GTK_CHECK_VERSION(3,0,0)
!       if (was_visible)
!           gtk_widget_queue_resize(GTK_WIDGET(container));
  #endif
!       form->children = g_list_remove_link(form->children, tmp_list);
!       g_list_free_1(tmp_list);
!       g_free(child);
!     }
  }
  
      static void
--- 610,641 ----
        tmp_list = tmp_list->next;
      }
  
!     if (tmp_list == NULL)
!       return;
! 
  #if GTK_CHECK_VERSION(3,0,0)
!     const gboolean was_visible = gtk_widget_get_visible(widget);
  #endif
!     if (child->window)
!     {
!       g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget),
!               FUNC2GENERIC(&form_child_map), child);
!       g_signal_handlers_disconnect_by_func(G_OBJECT(child->widget),
!               FUNC2GENERIC(&form_child_unmap), child);
  
!       // FIXME: This will cause problems for reparenting NO_WINDOW
!       // widgets out of a GtkForm
!       gdk_window_set_user_data(child->window, NULL);
!       gdk_window_destroy(child->window);
!     }
!     gtk_widget_unparent(widget);
  #if GTK_CHECK_VERSION(3,0,0)
!     if (was_visible)
!       gtk_widget_queue_resize(GTK_WIDGET(container));
  #endif
!     form->children = g_list_remove_link(form->children, tmp_list);
!     g_list_free_1(tmp_list);
!     g_free(child);
  }
  
      static void
*** ../vim-9.0.1157/src/gui_gtk_x11.c   2022-12-01 19:40:51.796701665 +0000
--- src/gui_gtk_x11.c   2023-01-08 13:38:57.105602496 +0000
***************
*** 2435,2450 ****
      GnomeClient *client;
  
      client = gnome_master_client();
  
!     if (client != NULL)
!     {
!       // Must use the deprecated gtk_signal_connect() for compatibility
!       // with GNOME 1.  Arrgh, zombies!
!       gtk_signal_connect(GTK_OBJECT(client), "save_yourself",
!                          GTK_SIGNAL_FUNC(&sm_client_save_yourself), NULL);
!       gtk_signal_connect(GTK_OBJECT(client), "die",
!                          GTK_SIGNAL_FUNC(&sm_client_die), NULL);
!     }
  }
  
  #else // !USE_GNOME_SESSION
--- 2435,2449 ----
      GnomeClient *client;
  
      client = gnome_master_client();
+     if (client == NULL)
+       return;
  
!     // Must use the deprecated gtk_signal_connect() for compatibility
!     // with GNOME 1.  Arrgh, zombies!
!     gtk_signal_connect(GTK_OBJECT(client), "save_yourself",
!           GTK_SIGNAL_FUNC(&sm_client_save_yourself), NULL);
!     gtk_signal_connect(GTK_OBJECT(client), "die",
!           GTK_SIGNAL_FUNC(&sm_client_die), NULL);
  }
  
  #else // !USE_GNOME_SESSION
***************
*** 3379,3391 ****
        gint            idx,
        gpointer        data UNUSED)
  {
!     if (!ignore_tabline_evt)
!     {
!       if ((tabpage_index(curtab) - 1) < idx)
!           tabpage_move(idx + 1);
!       else
!           tabpage_move(idx);
!     }
  }
  # endif
  
--- 3378,3390 ----
        gint            idx,
        gpointer        data UNUSED)
  {
!     if (ignore_tabline_evt)
!       return;
! 
!     if ((tabpage_index(curtab) - 1) < idx)
!       tabpage_move(idx + 1);
!     else
!       tabpage_move(idx);
  }
  # endif
  
***************
*** 4069,4083 ****
      void
  gui_mch_forked(void)
  {
!     if (using_gnome)
!     {
!       GnomeClient *client;
  
!       client = gnome_master_client();
  
!       if (client != NULL)
!           gnome_client_set_process_id(client, getpid());
!     }
  }
  #endif // USE_GNOME_SESSION
  
--- 4068,4082 ----
      void
  gui_mch_forked(void)
  {
!     if (!using_gnome)
!       return;
! 
!     GnomeClient *client;
  
!     client = gnome_master_client();
  
!     if (client != NULL)
!       gnome_client_set_process_id(client, getpid());
  }
  #endif // USE_GNOME_SESSION
  
***************
*** 6860,6870 ****
      void
  clip_mch_lose_selection(Clipboard_T *cbd UNUSED)
  {
!     if (!in_selection_clear_event)
!     {
!       gtk_selection_owner_set(NULL, cbd->gtk_sel_atom, gui.event_time);
!       gui_mch_update();
!     }
  }
  
  /*
--- 6859,6869 ----
      void
  clip_mch_lose_selection(Clipboard_T *cbd UNUSED)
  {
!     if (in_selection_clear_event)
!       return;
! 
!     gtk_selection_owner_set(NULL, cbd->gtk_sel_atom, gui.event_time);
!     gui_mch_update();
  }
  
  /*
***************
*** 7029,7049 ****
      void
  gui_mch_mousehide(int hide)
  {
!     if (gui.pointer_hidden != hide)
      {
!       gui.pointer_hidden = hide;
!       if (gtk_widget_get_window(gui.drawarea) && gui.blank_pointer != NULL)
!       {
!           if (hide)
!               gdk_window_set_cursor(gtk_widget_get_window(gui.drawarea),
!                       gui.blank_pointer);
!           else
  #ifdef FEAT_MOUSESHAPE
!               mch_set_mouse_shape(last_shape);
  #else
!               gdk_window_set_cursor(gtk_widget_get_window(gui.drawarea), 
NULL);
  #endif
-       }
      }
  }
  
--- 7028,7048 ----
      void
  gui_mch_mousehide(int hide)
  {
!     if (gui.pointer_hidden == hide)
!       return;
! 
!     gui.pointer_hidden = hide;
!     if (gtk_widget_get_window(gui.drawarea) && gui.blank_pointer != NULL)
      {
!       if (hide)
!           gdk_window_set_cursor(gtk_widget_get_window(gui.drawarea),
!                   gui.blank_pointer);
!       else
  #ifdef FEAT_MOUSESHAPE
!           mch_set_mouse_shape(last_shape);
  #else
!       gdk_window_set_cursor(gtk_widget_get_window(gui.drawarea), NULL);
  #endif
      }
  }
  
***************
*** 7132,7272 ****
  
      sign = (GdkPixbuf *)sign_get_image(typenr);
  
!     if (sign != NULL && gui.drawarea != NULL
!           && gtk_widget_get_window(gui.drawarea) != NULL)
!     {
!       int width;
!       int height;
!       int xoffset;
!       int yoffset;
!       int need_scale;
  
!       width  = gdk_pixbuf_get_width(sign);
!       height = gdk_pixbuf_get_height(sign);
!       /*
!        * Decide whether we need to scale.  Allow one pixel of border
!        * width to be cut off, in order to avoid excessive scaling for
!        * tiny differences in font size.
!        * Do scale to fit the height to avoid gaps because of linespacing.
!        */
!       need_scale = (width > SIGN_WIDTH + 2
!                     || height != SIGN_HEIGHT
!                     || (width < 3 * SIGN_WIDTH / 4
!                         && height < 3 * SIGN_HEIGHT / 4));
!       if (need_scale)
!       {
!           double  aspect;
!           int     w = width;
!           int     h = height;
! 
!           // Keep the original aspect ratio
!           aspect = (double)height / (double)width;
!           width  = (double)SIGN_WIDTH * SIGN_ASPECT / aspect;
!           width  = MIN(width, SIGN_WIDTH);
!           if (((double)(MAX(height, SIGN_HEIGHT)) /
!                (double)(MIN(height, SIGN_HEIGHT))) < 1.15)
!           {
!               // Change the aspect ratio by at most 15% to fill the
!               // available space completely.
!               height = (double)SIGN_HEIGHT * SIGN_ASPECT / aspect;
!               height = MIN(height, SIGN_HEIGHT);
!           }
!           else
!               height = (double)width * aspect;
  
!           if (w == width && h == height)
!           {
!               // no change in dimensions; don't decrease reference counter
!               // (below)
!               need_scale = FALSE;
!           }
!           else
!           {
!               // This doesn't seem to be worth caching, and doing so would
!               // complicate the code quite a bit.
!               sign = gdk_pixbuf_scale_simple(sign, width, height,
!                                                        GDK_INTERP_BILINEAR);
!               if (sign == NULL)
!                   return; // out of memory
!           }
        }
  
!       // The origin is the upper-left corner of the pixmap.  Therefore
!       // these offset may become negative if the pixmap is smaller than
!       // the 2x1 cells reserved for the sign icon.
!       xoffset = (width  - SIGN_WIDTH)  / 2;
!       yoffset = (height - SIGN_HEIGHT) / 2;
  
  # if GTK_CHECK_VERSION(3,0,0)
!       {
!           cairo_t         *cr;
!           cairo_surface_t *bg_surf;
!           cairo_t         *bg_cr;
!           cairo_surface_t *sign_surf;
!           cairo_t         *sign_cr;
! 
!           cr = cairo_create(gui.surface);
! 
!           bg_surf = cairo_surface_create_similar(gui.surface,
!                   cairo_surface_get_content(gui.surface),
!                   SIGN_WIDTH, SIGN_HEIGHT);
!           bg_cr = cairo_create(bg_surf);
!           cairo_set_source_rgba(bg_cr,
!                   gui.bgcolor->red, gui.bgcolor->green, gui.bgcolor->blue,
!                   gui.bgcolor->alpha);
!           cairo_paint(bg_cr);
! 
!           sign_surf = cairo_surface_create_similar(gui.surface,
!                   cairo_surface_get_content(gui.surface),
!                   SIGN_WIDTH, SIGN_HEIGHT);
!           sign_cr = cairo_create(sign_surf);
!           gdk_cairo_set_source_pixbuf(sign_cr, sign, -xoffset, -yoffset);
!           cairo_paint(sign_cr);
! 
!           cairo_set_operator(sign_cr, CAIRO_OPERATOR_DEST_OVER);
!           cairo_set_source_surface(sign_cr, bg_surf, 0, 0);
!           cairo_paint(sign_cr);
! 
!           cairo_set_source_surface(cr, sign_surf, FILL_X(col), FILL_Y(row));
!           cairo_paint(cr);
! 
!           cairo_destroy(sign_cr);
!           cairo_surface_destroy(sign_surf);
!           cairo_destroy(bg_cr);
!           cairo_surface_destroy(bg_surf);
!           cairo_destroy(cr);
  
!           gtk_widget_queue_draw_area(gui.drawarea,
!                   FILL_X(col), FILL_Y(col), width, height);
  
!       }
  # else // !GTK_CHECK_VERSION(3,0,0)
!       gdk_gc_set_foreground(gui.text_gc, gui.bgcolor);
  
!       gdk_draw_rectangle(gui.drawarea->window,
!                          gui.text_gc,
!                          TRUE,
!                          FILL_X(col),
!                          FILL_Y(row),
!                          SIGN_WIDTH,
!                          SIGN_HEIGHT);
  
!       gdk_pixbuf_render_to_drawable_alpha(sign,
!                                           gui.drawarea->window,
!                                           MAX(0, xoffset),
!                                           MAX(0, yoffset),
!                                           FILL_X(col) - MIN(0, xoffset),
!                                           FILL_Y(row) - MIN(0, yoffset),
!                                           MIN(width,  SIGN_WIDTH),
!                                           MIN(height, SIGN_HEIGHT),
!                                           GDK_PIXBUF_ALPHA_BILEVEL,
!                                           127,
!                                           GDK_RGB_DITHER_NORMAL,
!                                           0, 0);
  # endif // !GTK_CHECK_VERSION(3,0,0)
!       if (need_scale)
!           g_object_unref(sign);
!     }
  }
  
      void *
--- 7131,7271 ----
  
      sign = (GdkPixbuf *)sign_get_image(typenr);
  
!     if (sign == NULL || gui.drawarea == NULL
!           || gtk_widget_get_window(gui.drawarea) == NULL)
!       return;
  
!     int width;
!     int height;
!     int xoffset;
!     int yoffset;
!     int need_scale;
  
!     width  = gdk_pixbuf_get_width(sign);
!     height = gdk_pixbuf_get_height(sign);
!     /*
!      * Decide whether we need to scale.  Allow one pixel of border
!      * width to be cut off, in order to avoid excessive scaling for
!      * tiny differences in font size.
!      * Do scale to fit the height to avoid gaps because of linespacing.
!      */
!     need_scale = (width > SIGN_WIDTH + 2
!           || height != SIGN_HEIGHT
!           || (width < 3 * SIGN_WIDTH / 4
!               && height < 3 * SIGN_HEIGHT / 4));
!     if (need_scale)
!     {
!       double  aspect;
!       int         w = width;
!       int         h = height;
! 
!       // Keep the original aspect ratio
!       aspect = (double)height / (double)width;
!       width  = (double)SIGN_WIDTH * SIGN_ASPECT / aspect;
!       width  = MIN(width, SIGN_WIDTH);
!       if (((double)(MAX(height, SIGN_HEIGHT)) /
!                   (double)(MIN(height, SIGN_HEIGHT))) < 1.15)
!       {
!           // Change the aspect ratio by at most 15% to fill the
!           // available space completely.
!           height = (double)SIGN_HEIGHT * SIGN_ASPECT / aspect;
!           height = MIN(height, SIGN_HEIGHT);
        }
+       else
+           height = (double)width * aspect;
+ 
+       if (w == width && h == height)
+       {
+           // no change in dimensions; don't decrease reference counter
+           // (below)
+           need_scale = FALSE;
+       }
+       else
+       {
+           // This doesn't seem to be worth caching, and doing so would
+           // complicate the code quite a bit.
+           sign = gdk_pixbuf_scale_simple(sign, width, height,
+                   GDK_INTERP_BILINEAR);
+           if (sign == NULL)
+               return; // out of memory
+       }
+     }
  
!     // The origin is the upper-left corner of the pixmap.  Therefore
!     // these offset may become negative if the pixmap is smaller than
!     // the 2x1 cells reserved for the sign icon.
!     xoffset = (width  - SIGN_WIDTH)  / 2;
!     yoffset = (height - SIGN_HEIGHT) / 2;
  
  # if GTK_CHECK_VERSION(3,0,0)
!     {
!       cairo_t     *cr;
!       cairo_surface_t *bg_surf;
!       cairo_t     *bg_cr;
!       cairo_surface_t *sign_surf;
!       cairo_t     *sign_cr;
  
!       cr = cairo_create(gui.surface);
  
!       bg_surf = cairo_surface_create_similar(gui.surface,
!               cairo_surface_get_content(gui.surface),
!               SIGN_WIDTH, SIGN_HEIGHT);
!       bg_cr = cairo_create(bg_surf);
!       cairo_set_source_rgba(bg_cr,
!               gui.bgcolor->red, gui.bgcolor->green, gui.bgcolor->blue,
!               gui.bgcolor->alpha);
!       cairo_paint(bg_cr);
! 
!       sign_surf = cairo_surface_create_similar(gui.surface,
!               cairo_surface_get_content(gui.surface),
!               SIGN_WIDTH, SIGN_HEIGHT);
!       sign_cr = cairo_create(sign_surf);
!       gdk_cairo_set_source_pixbuf(sign_cr, sign, -xoffset, -yoffset);
!       cairo_paint(sign_cr);
! 
!       cairo_set_operator(sign_cr, CAIRO_OPERATOR_DEST_OVER);
!       cairo_set_source_surface(sign_cr, bg_surf, 0, 0);
!       cairo_paint(sign_cr);
! 
!       cairo_set_source_surface(cr, sign_surf, FILL_X(col), FILL_Y(row));
!       cairo_paint(cr);
! 
!       cairo_destroy(sign_cr);
!       cairo_surface_destroy(sign_surf);
!       cairo_destroy(bg_cr);
!       cairo_surface_destroy(bg_surf);
!       cairo_destroy(cr);
! 
!       gtk_widget_queue_draw_area(gui.drawarea,
!               FILL_X(col), FILL_Y(col), width, height);
! 
!     }
  # else // !GTK_CHECK_VERSION(3,0,0)
!     gdk_gc_set_foreground(gui.text_gc, gui.bgcolor);
  
!     gdk_draw_rectangle(gui.drawarea->window,
!           gui.text_gc,
!           TRUE,
!           FILL_X(col),
!           FILL_Y(row),
!           SIGN_WIDTH,
!           SIGN_HEIGHT);
  
!     gdk_pixbuf_render_to_drawable_alpha(sign,
!           gui.drawarea->window,
!           MAX(0, xoffset),
!           MAX(0, yoffset),
!           FILL_X(col) - MIN(0, xoffset),
!           FILL_Y(row) - MIN(0, yoffset),
!           MIN(width,  SIGN_WIDTH),
!           MIN(height, SIGN_HEIGHT),
!           GDK_PIXBUF_ALPHA_BILEVEL,
!           127,
!           GDK_RGB_DITHER_NORMAL,
!           0, 0);
  # endif // !GTK_CHECK_VERSION(3,0,0)
!     if (need_scale)
!       g_object_unref(sign);
  }
  
      void *
*** ../vim-9.0.1157/src/gui_motif.c     2022-10-04 16:23:39.014042183 +0100
--- src/gui_motif.c     2023-01-08 13:38:57.105602496 +0000
***************
*** 979,992 ****
      XmString  label;
  
      // Add accelerator text, if there is one
!     if (menu->actext != NULL && menu->id != (Widget)0)
!     {
!       label = XmStringCreate((char *)menu->actext, STRING_TAG);
!       if (label == NULL)
!           return;
!       XtVaSetValues(menu->id, XmNacceleratorText, label, NULL);
!       XmStringFree(label);
!     }
  }
  
      void
--- 979,992 ----
      XmString  label;
  
      // Add accelerator text, if there is one
!     if (menu->actext == NULL || menu->id == (Widget)0)
!       return;
! 
!     label = XmStringCreate((char *)menu->actext, STRING_TAG);
!     if (label == NULL)
!       return;
!     XtVaSetValues(menu->id, XmNacceleratorText, label, NULL);
!     XmStringFree(label);
  }
  
      void
***************
*** 1573,1616 ****
        menu->submenu_id = (Widget)0;
      }
  
!     if (menu->id != (Widget)0)
!     {
!       Widget      parent;
  
!       parent = XtParent(menu->id);
  #if defined(FEAT_TOOLBAR) && defined(FEAT_BEVAL_GUI)
!       if (parent == toolBar && menu->tip != NULL)
!       {
!           // We try to destroy this before the actual menu, because there are
!           // callbacks, etc. that will be unregistered during the tooltip
!           // destruction.
!           //
!           // If you call "gui_mch_destroy_beval_area()" after destroying
!           // menu->id, then the tooltip's window will have already been
!           // deallocated by Xt, and unknown behaviour will ensue (probably
!           // a core dump).
!           gui_mch_destroy_beval_area(menu->tip);
!           menu->tip = NULL;
!       }
! #endif
!       XtDestroyWidget(menu->id);
!       menu->id = (Widget)0;
!       if (parent == menuBar)
!           gui_mch_compute_menu_height((Widget)0);
  #ifdef FEAT_TOOLBAR
!       else if (parent == toolBar)
!       {
!           Cardinal    num_children;
  
!           // When removing last toolbar item, don't display the toolbar.
!           XtVaGetValues(toolBar, XmNnumChildren, &num_children, NULL);
!           if (num_children == 0)
!               gui_mch_show_toolbar(FALSE);
!           else
!               gui.toolbar_height = gui_mch_compute_toolbar_height();
!       }
! #endif
      }
  }
  
      void
--- 1573,1616 ----
        menu->submenu_id = (Widget)0;
      }
  
!     if (menu->id == (Widget)0)
!       return;
  
!     Widget        parent;
! 
!     parent = XtParent(menu->id);
  #if defined(FEAT_TOOLBAR) && defined(FEAT_BEVAL_GUI)
!     if (parent == toolBar && menu->tip != NULL)
!     {
!       // We try to destroy this before the actual menu, because there are
!       // callbacks, etc. that will be unregistered during the tooltip
!       // destruction.
!       //
!       // If you call "gui_mch_destroy_beval_area()" after destroying
!       // menu->id, then the tooltip's window will have already been
!       // deallocated by Xt, and unknown behaviour will ensue (probably
!       // a core dump).
!       gui_mch_destroy_beval_area(menu->tip);
!       menu->tip = NULL;
!     }
! #endif
!     XtDestroyWidget(menu->id);
!     menu->id = (Widget)0;
!     if (parent == menuBar)
!       gui_mch_compute_menu_height((Widget)0);
  #ifdef FEAT_TOOLBAR
!     else if (parent == toolBar)
!     {
!       Cardinal    num_children;
  
!       // When removing last toolbar item, don't display the toolbar.
!       XtVaGetValues(toolBar, XmNnumChildren, &num_children, NULL);
!       if (num_children == 0)
!           gui_mch_show_toolbar(FALSE);
!       else
!           gui.toolbar_height = gui_mch_compute_toolbar_height();
      }
+ #endif
  }
  
      void
***************
*** 1630,1648 ****
      void
  gui_mch_def_colors(void)
  {
!     if (gui.in_use)
!     {
!       gui.menu_fg_pixel = gui_get_color((char_u *)gui.rsrc_menu_fg_name);
!       gui.menu_bg_pixel = gui_get_color((char_u *)gui.rsrc_menu_bg_name);
!       gui.scroll_fg_pixel = gui_get_color((char_u *)gui.rsrc_scroll_fg_name);
!       gui.scroll_bg_pixel = gui_get_color((char_u *)gui.rsrc_scroll_bg_name);
  #ifdef FEAT_BEVAL_GUI
!       gui.tooltip_fg_pixel =
!                       gui_get_color((char_u *)gui.rsrc_tooltip_fg_name);
!       gui.tooltip_bg_pixel =
!                       gui_get_color((char_u *)gui.rsrc_tooltip_bg_name);
  #endif
-     }
  }
  
  
--- 1630,1648 ----
      void
  gui_mch_def_colors(void)
  {
!     if (!gui.in_use)
!       return;
! 
!     gui.menu_fg_pixel = gui_get_color((char_u *)gui.rsrc_menu_fg_name);
!     gui.menu_bg_pixel = gui_get_color((char_u *)gui.rsrc_menu_bg_name);
!     gui.scroll_fg_pixel = gui_get_color((char_u *)gui.rsrc_scroll_fg_name);
!     gui.scroll_bg_pixel = gui_get_color((char_u *)gui.rsrc_scroll_bg_name);
  #ifdef FEAT_BEVAL_GUI
!     gui.tooltip_fg_pixel =
!       gui_get_color((char_u *)gui.rsrc_tooltip_fg_name);
!     gui.tooltip_bg_pixel =
!       gui_get_color((char_u *)gui.rsrc_tooltip_bg_name);
  #endif
  }
  
  
***************
*** 1674,1703 ****
      int               w,
      int               h)
  {
!     if (sb->id != (Widget)0)
      {
!       if (sb->type == SBAR_LEFT || sb->type == SBAR_RIGHT)
!       {
!           if (y == 0)
!               h -= gui.border_offset;
!           else
!               y -= gui.border_offset;
!           XtVaSetValues(sb->id,
!                         XmNtopOffset, y,
!                         XmNbottomOffset, -y - h,
!                         XmNwidth, w,
!                         NULL);
!       }
        else
!           XtVaSetValues(sb->id,
!                         XmNtopOffset, y,
!                         XmNleftOffset, x,
!                         XmNrightOffset, gui.which_scrollbars[SBAR_RIGHT]
!                                                   ? gui.scrollbar_width : 0,
!                         XmNheight, h,
!                         NULL);
!       XtManageChild(sb->id);
      }
  }
  
      int
--- 1674,1703 ----
      int               w,
      int               h)
  {
!     if (sb->id == (Widget)0)
!       return;
! 
!     if (sb->type == SBAR_LEFT || sb->type == SBAR_RIGHT)
      {
!       if (y == 0)
!           h -= gui.border_offset;
        else
!           y -= gui.border_offset;
!       XtVaSetValues(sb->id,
!               XmNtopOffset, y,
!               XmNbottomOffset, -y - h,
!               XmNwidth, w,
!               NULL);
      }
+     else
+       XtVaSetValues(sb->id,
+               XmNtopOffset, y,
+               XmNleftOffset, x,
+               XmNrightOffset, gui.which_scrollbars[SBAR_RIGHT]
+               ? gui.scrollbar_width : 0,
+               XmNheight, h,
+               NULL);
+     XtManageChild(sb->id);
  }
  
      int
***************
*** 1732,1783 ****
      Arg               args[16];
      int               n;
  
!     if (sb->id != (Widget)0)
      {
!       n = 0;
!       if (flag)
        {
            switch (sb->type)
            {
                case SBAR_LEFT:
!                   XtSetArg(args[n], XmNleftOffset, gui.scrollbar_width); n++;
                    break;
  
                case SBAR_RIGHT:
!                   XtSetArg(args[n], XmNrightOffset, gui.scrollbar_width); n++;
                    break;
  
                case SBAR_BOTTOM:
!                   XtSetArg(args[n], XmNbottomOffset, 
gui.scrollbar_height);n++;
                    break;
            }
            XtSetValues(textArea, args, n);
-           XtManageChild(sb->id);
-       }
-       else
-       {
-           if (!gui.which_scrollbars[sb->type])
-           {
-               // The scrollbars of this type are all disabled, adjust the
-               // textArea attachment offset.
-               switch (sb->type)
-               {
-                   case SBAR_LEFT:
-                       XtSetArg(args[n], XmNleftOffset, 0); n++;
-                       break;
- 
-                   case SBAR_RIGHT:
-                       XtSetArg(args[n], XmNrightOffset, 0); n++;
-                       break;
- 
-                   case SBAR_BOTTOM:
-                       XtSetArg(args[n], XmNbottomOffset, 0);n++;
-                       break;
-               }
-               XtSetValues(textArea, args, n);
-           }
-           XtUnmanageChild(sb->id);
        }
      }
  }
  
--- 1732,1783 ----
      Arg               args[16];
      int               n;
  
!     if (sb->id == (Widget)0)
!       return;
! 
!     n = 0;
!     if (flag)
      {
!       switch (sb->type)
!       {
!           case SBAR_LEFT:
!               XtSetArg(args[n], XmNleftOffset, gui.scrollbar_width); n++;
!               break;
! 
!           case SBAR_RIGHT:
!               XtSetArg(args[n], XmNrightOffset, gui.scrollbar_width); n++;
!               break;
! 
!           case SBAR_BOTTOM:
!               XtSetArg(args[n], XmNbottomOffset, gui.scrollbar_height);n++;
!               break;
!       }
!       XtSetValues(textArea, args, n);
!       XtManageChild(sb->id);
!     }
!     else
!     {
!       if (!gui.which_scrollbars[sb->type])
        {
+           // The scrollbars of this type are all disabled, adjust the
+           // textArea attachment offset.
            switch (sb->type)
            {
                case SBAR_LEFT:
!                   XtSetArg(args[n], XmNleftOffset, 0); n++;
                    break;
  
                case SBAR_RIGHT:
!                   XtSetArg(args[n], XmNrightOffset, 0); n++;
                    break;
  
                case SBAR_BOTTOM:
!                   XtSetArg(args[n], XmNbottomOffset, 0);n++;
                    break;
            }
            XtSetValues(textArea, args, n);
        }
+       XtUnmanageChild(sb->id);
      }
  }
  
***************
*** 1817,1833 ****
  
      sb->id = XtCreateWidget("scrollBar",
            xmScrollBarWidgetClass, textAreaForm, args, n);
  
!     if (sb->id != (Widget)0)
!     {
!       gui_mch_set_scrollbar_colors(sb);
!       XtAddCallback(sb->id, XmNvalueChangedCallback,
!                     scroll_cb, (XtPointer)sb->ident);
!       XtAddCallback(sb->id, XmNdragCallback,
!                     scroll_cb, (XtPointer)sb->ident);
!       XtAddEventHandler(sb->id, KeyPressMask, FALSE, gui_x11_key_hit_cb,
            (XtPointer)0);
-     }
  }
  
      void
--- 1817,1832 ----
  
      sb->id = XtCreateWidget("scrollBar",
            xmScrollBarWidgetClass, textAreaForm, args, n);
+     if (sb->id == (Widget)0)
+       return;
  
!     gui_mch_set_scrollbar_colors(sb);
!     XtAddCallback(sb->id, XmNvalueChangedCallback,
!           scroll_cb, (XtPointer)sb->ident);
!     XtAddCallback(sb->id, XmNdragCallback,
!           scroll_cb, (XtPointer)sb->ident);
!     XtAddEventHandler(sb->id, KeyPressMask, FALSE, gui_x11_key_hit_cb,
            (XtPointer)0);
  }
  
      void
*** ../vim-9.0.1157/src/gui_photon.c    2021-12-31 20:47:48.000000000 +0000
--- src/gui_photon.c    2023-01-08 13:38:57.109602493 +0000
***************
*** 992,1010 ****
      char **new_titles = NULL;
  
      new_titles = ALLOC_MULT(char *, (num_panels + 1));
!     if (new_titles != NULL)
!     {
!       if (num_panels > 0)
!           memcpy(new_titles, panel_titles, num_panels * sizeof(char **));
  
!       new_titles[ num_panels++ ] = name;
  
!       PtSetResource(gui.vimPanelGroup, Pt_ARG_PG_PANEL_TITLES, new_titles,
!               num_panels);
  
!       vim_free(panel_titles);
!       panel_titles = new_titles;
!     }
  }
  
      static void
--- 992,1010 ----
      char **new_titles = NULL;
  
      new_titles = ALLOC_MULT(char *, (num_panels + 1));
!     if (new_titles == NULL)
!       return;
  
!     if (num_panels > 0)
!       memcpy(new_titles, panel_titles, num_panels * sizeof(char **));
  
!     new_titles[ num_panels++ ] = name;
  
!     PtSetResource(gui.vimPanelGroup, Pt_ARG_PG_PANEL_TITLES, new_titles,
!           num_panels);
! 
!     vim_free(panel_titles);
!     panel_titles = new_titles;
  }
  
      static void
***************
*** 1901,1921 ****
      void
  gui_mch_mousehide(int hide)
  {
!     if (gui.pointer_hidden != hide)
!     {
!       gui.pointer_hidden = hide;
  #ifdef FEAT_MOUSESHAPE
!       if (hide)
!           PtSetResource(gui.vimTextArea, Pt_ARG_CURSOR_TYPE,
!                   Ph_CURSOR_NONE, 0);
!       else
!           mch_set_mouse_shape(last_shape);
! #else
        PtSetResource(gui.vimTextArea, Pt_ARG_CURSOR_TYPE,
!               (hide == MOUSE_SHOW) ? GUI_PH_MOUSE_TYPE : Ph_CURSOR_NONE,
!               0);
  #endif
-     }
  }
  
      void
--- 1901,1921 ----
      void
  gui_mch_mousehide(int hide)
  {
!     if (gui.pointer_hidden == hide)
!       return;
! 
!     gui.pointer_hidden = hide;
  #ifdef FEAT_MOUSESHAPE
!     if (hide)
        PtSetResource(gui.vimTextArea, Pt_ARG_CURSOR_TYPE,
!               Ph_CURSOR_NONE, 0);
!     else
!       mch_set_mouse_shape(last_shape);
! #else
!     PtSetResource(gui.vimTextArea, Pt_ARG_CURSOR_TYPE,
!           (hide == MOUSE_SHOW) ? GUI_PH_MOUSE_TYPE : Ph_CURSOR_NONE,
!           0);
  #endif
  }
  
      void
*** ../vim-9.0.1157/src/gui_w32.c       2022-12-30 16:54:53.452987924 +0000
--- src/gui_w32.c       2023-01-08 13:38:57.109602493 +0000
***************
*** 434,445 ****
      static void
  directx_binddc(void)
  {
!     if (s_textArea != NULL)
!     {
!       RECT    rect;
!       GetClientRect(s_textArea, &rect);
!       DWriteContext_BindDC(s_dwc, s_hdc, &rect);
!     }
  }
  #endif
  
--- 434,445 ----
      static void
  directx_binddc(void)
  {
!     if (s_textArea == NULL)
!       return;
! 
!     RECT      rect;
!     GetClientRect(s_textArea, &rect);
!     DWriteContext_BindDC(s_dwc, s_hdc, &rect);
  }
  #endif
  
***************
*** 663,676 ****
  {
      MSG msg;
  
!     if (blink_timer != 0)
!     {
!       KillTimer(NULL, blink_timer);
!       // Eat spurious WM_TIMER messages
!       while (PeekMessageW(&msg, s_hwnd, WM_TIMER, WM_TIMER, PM_REMOVE))
!           ;
!       blink_timer = 0;
!     }
  }
  
  /*
--- 663,676 ----
  {
      MSG msg;
  
!     if (blink_timer == 0)
!       return;
! 
!     KillTimer(NULL, blink_timer);
!     // Eat spurious WM_TIMER messages
!     while (PeekMessageW(&msg, s_hwnd, WM_TIMER, WM_TIMER, PM_REMOVE))
!       ;
!     blink_timer = 0;
  }
  
  /*
***************
*** 888,894 ****
      modifiers = get_active_modifiers();
  
      ch = simplify_key(ch, &modifiers);
!     
      // Some keys need adjustment when the Ctrl modifier is used.
      ++no_reduce_keys;
      ch = may_adjust_key_for_ctrl(modifiers, ch);
--- 888,894 ----
      modifiers = get_active_modifiers();
  
      ch = simplify_key(ch, &modifiers);
! 
      // Some keys need adjustment when the Ctrl modifier is used.
      ++no_reduce_keys;
      ch = may_adjust_key_for_ctrl(modifiers, ch);
***************
*** 1034,1096 ****
        else
            button = MOUSE_LEFT;
      }
-     if (button >= 0)
-     {
-       repeated_click = ((int)(currentTime - s_prevTime) < p_mouset);
  
        /*
!        * Holding down the left and right buttons simulates pushing the middle
!        * button.
         */
!       if (repeated_click
!               && ((button == MOUSE_LEFT && s_button_pending == MOUSE_RIGHT)
!                   || (button == MOUSE_RIGHT
!                                         && s_button_pending == MOUSE_LEFT)))
        {
!           /*
!            * Hmm, gui.c will ignore more than one button down at a time, so
!            * pretend we let go of it first.
!            */
!           gui_send_mouse_event(MOUSE_RELEASE, x, y, FALSE, 0x0);
!           button = MOUSE_MIDDLE;
!           repeated_click = FALSE;
            s_button_pending = -1;
-           _OnMouseEvent(button, x, y, repeated_click, keyFlags);
        }
!       else if ((repeated_click)
!               || (mouse_model_popup() && (button == MOUSE_RIGHT)))
!       {
!           if (s_button_pending > -1)
!           {
!               _OnMouseEvent(s_button_pending, x, y, FALSE, keyFlags);
!               s_button_pending = -1;
!           }
!           // TRACE("Button down at x %d, y %d\n", x, y);
!           _OnMouseEvent(button, x, y, repeated_click, keyFlags);
!       }
!       else
!       {
!           /*
!            * If this is the first press (i.e. not a multiple click) don't
!            * action immediately, but store and wait for:
!            * i) button-up
!            * ii) mouse move
!            * iii) another button press
!            * before using it.
!            * This enables us to make left+right simulate middle button,
!            * without left or right being actioned first.  The side-effect is
!            * that if you click and hold the mouse without dragging, the
!            * cursor doesn't move until you release the button. In practice
!            * this is hardly a problem.
!            */
!           s_button_pending = button;
!           s_x_pending = x;
!           s_y_pending = y;
!           s_kFlags_pending = keyFlags;
!       }
! 
!       s_prevTime = currentTime;
      }
  }
  
      static void
--- 1034,1097 ----
        else
            button = MOUSE_LEFT;
      }
  
+     if (button < 0)
+       return;
+ 
+     repeated_click = ((int)(currentTime - s_prevTime) < p_mouset);
+ 
+     /*
+      * Holding down the left and right buttons simulates pushing the middle
+      * button.
+      */
+     if (repeated_click
+           && ((button == MOUSE_LEFT && s_button_pending == MOUSE_RIGHT)
+               || (button == MOUSE_RIGHT
+                   && s_button_pending == MOUSE_LEFT)))
+     {
        /*
!        * Hmm, gui.c will ignore more than one button down at a time, so
!        * pretend we let go of it first.
         */
!       gui_send_mouse_event(MOUSE_RELEASE, x, y, FALSE, 0x0);
!       button = MOUSE_MIDDLE;
!       repeated_click = FALSE;
!       s_button_pending = -1;
!       _OnMouseEvent(button, x, y, repeated_click, keyFlags);
!     }
!     else if ((repeated_click)
!           || (mouse_model_popup() && (button == MOUSE_RIGHT)))
!     {
!       if (s_button_pending > -1)
        {
!           _OnMouseEvent(s_button_pending, x, y, FALSE, keyFlags);
            s_button_pending = -1;
        }
!       // TRACE("Button down at x %d, y %d\n", x, y);
!       _OnMouseEvent(button, x, y, repeated_click, keyFlags);
!     }
!     else
!     {
!       /*
!        * If this is the first press (i.e. not a multiple click) don't
!        * action immediately, but store and wait for:
!        * i) button-up
!        * ii) mouse move
!        * iii) another button press
!        * before using it.
!        * This enables us to make left+right simulate middle button,
!        * without left or right being actioned first.  The side-effect is
!        * that if you click and hold the mouse without dragging, the
!        * cursor doesn't move until you release the button. In practice
!        * this is hardly a problem.
!        */
!       s_button_pending = button;
!       s_x_pending = x;
!       s_y_pending = y;
!       s_kFlags_pending = keyFlags;
      }
+ 
+     s_prevTime = currentTime;
  }
  
      static void
***************
*** 1233,1255 ****
        flags = FRD_REPLACEALL;
      }
  
!     if (flags != 0)
!     {
!       char_u  *p, *q;
  
!       // Call the generic GUI function to do the actual work.
!       if (s_findrep_struct.Flags & FR_WHOLEWORD)
!           flags |= FRD_WHOLE_WORD;
!       if (s_findrep_struct.Flags & FR_MATCHCASE)
!           flags |= FRD_MATCH_CASE;
!       down = (s_findrep_struct.Flags & FR_DOWN) != 0;
!       p = utf16_to_enc(s_findrep_struct.lpstrFindWhat, NULL);
!       q = utf16_to_enc(s_findrep_struct.lpstrReplaceWith, NULL);
!       if (p != NULL && q != NULL)
!           gui_do_findrepl(flags, p, q, down);
!       vim_free(p);
!       vim_free(q);
!     }
  }
  #endif
  
--- 1234,1256 ----
        flags = FRD_REPLACEALL;
      }
  
!     if (flags == 0)
!       return;
  
!     char_u    *p, *q;
! 
!     // Call the generic GUI function to do the actual work.
!     if (s_findrep_struct.Flags & FR_WHOLEWORD)
!       flags |= FRD_WHOLE_WORD;
!     if (s_findrep_struct.Flags & FR_MATCHCASE)
!       flags |= FRD_MATCH_CASE;
!     down = (s_findrep_struct.Flags & FR_DOWN) != 0;
!     p = utf16_to_enc(s_findrep_struct.lpstrFindWhat, NULL);
!     q = utf16_to_enc(s_findrep_struct.lpstrReplaceWith, NULL);
!     if (p != NULL && q != NULL)
!       gui_do_findrepl(flags, p, q, down);
!     vim_free(p);
!     vim_free(q);
  }
  #endif
  
***************
*** 2932,2942 ****
      void
  gui_mch_mousehide(int hide)
  {
!     if (hide != gui.pointer_hidden)
!     {
!       ShowCursor(!hide);
!       gui.pointer_hidden = hide;
!     }
  }
  
  #ifdef FEAT_MENU
--- 2933,2943 ----
      void
  gui_mch_mousehide(int hide)
  {
!     if (hide == gui.pointer_hidden)
!       return;
! 
!     ShowCursor(!hide);
!     gui.pointer_hidden = hide;
  }
  
  #ifdef FEAT_MENU
***************
*** 2993,3025 ****
  _OnPaint(
      HWND hwnd)
  {
!     if (!IsMinimized(hwnd))
!     {
!       PAINTSTRUCT ps;
  
!       out_flush();        // make sure all output has been processed
!       (void)BeginPaint(hwnd, &ps);
  
!       // prevent multi-byte characters from misprinting on an invalid
!       // rectangle
!       if (has_mbyte)
!       {
!           RECT rect;
  
!           GetClientRect(hwnd, &rect);
!           ps.rcPaint.left = rect.left;
!           ps.rcPaint.right = rect.right;
!       }
  
!       if (!IsRectEmpty(&ps.rcPaint))
!       {
!           gui_redraw(ps.rcPaint.left, ps.rcPaint.top,
!                   ps.rcPaint.right - ps.rcPaint.left + 1,
!                   ps.rcPaint.bottom - ps.rcPaint.top + 1);
!       }
  
!       EndPaint(hwnd, &ps);
      }
  }
  
      static void
--- 2994,3026 ----
  _OnPaint(
      HWND hwnd)
  {
!     if (IsMinimized(hwnd))
!       return;
  
!     PAINTSTRUCT ps;
  
!     out_flush();          // make sure all output has been processed
!     (void)BeginPaint(hwnd, &ps);
  
!     // prevent multi-byte characters from misprinting on an invalid
!     // rectangle
!     if (has_mbyte)
!     {
!       RECT rect;
  
!       GetClientRect(hwnd, &rect);
!       ps.rcPaint.left = rect.left;
!       ps.rcPaint.right = rect.right;
!     }
  
!     if (!IsRectEmpty(&ps.rcPaint))
!     {
!       gui_redraw(ps.rcPaint.left, ps.rcPaint.top,
!               ps.rcPaint.right - ps.rcPaint.left + 1,
!               ps.rcPaint.bottom - ps.rcPaint.top + 1);
      }
+ 
+     EndPaint(hwnd, &ps);
  }
  
      static void
***************
*** 3904,3924 ****
  
      DragFinish(hDrop);
  
!     if (fnames != NULL)
!     {
!       int kbd_modifiers = get_active_modifiers();
  
!       if ((kbd_modifiers & MOD_MASK_SHIFT) != 0)
!           modifiers |= MOUSE_SHIFT;
!       if ((kbd_modifiers & MOD_MASK_CTRL) != 0)
!           modifiers |= MOUSE_CTRL;
!       if ((kbd_modifiers & MOD_MASK_ALT) != 0)
!           modifiers |= MOUSE_ALT;
  
!       gui_handle_drop(pt.x, pt.y, modifiers, fnames, cFiles);
  
!       s_need_activate = TRUE;
!     }
  }
  
      static int
--- 3905,3925 ----
  
      DragFinish(hDrop);
  
!     if (fnames == NULL)
!       return;
  
!     int kbd_modifiers = get_active_modifiers();
  
!     if ((kbd_modifiers & MOD_MASK_SHIFT) != 0)
!       modifiers |= MOUSE_SHIFT;
!     if ((kbd_modifiers & MOD_MASK_CTRL) != 0)
!       modifiers |= MOUSE_CTRL;
!     if ((kbd_modifiers & MOD_MASK_ALT) != 0)
!       modifiers |= MOUSE_ALT;
  
!     gui_handle_drop(pt.x, pt.y, modifiers, fnames, cFiles);
! 
!     s_need_activate = TRUE;
  }
  
      static int
***************
*** 4461,4471 ****
      static void
  destroy_sizing_tip(void)
  {
!     if (hwndTip != NULL)
!     {
!       DestroyWindow(hwndTip);
!       hwndTip = NULL;
!     }
  }
  
      static int
--- 4462,4472 ----
      static void
  destroy_sizing_tip(void)
  {
!     if (hwndTip == NULL)
!       return;
! 
!     DestroyWindow(hwndTip);
!     hwndTip = NULL;
  }
  
      static int
***************
*** 5844,5907 ****
      }
  # endif
  
!     if (pImmGetContext)           // if NULL imm32.dll wasn't loaded (yet)
      {
!       if (p_imdisable)
        {
!           if (hImcOld == (HIMC)0)
!           {
!               hImcOld = pImmGetContext(s_hwnd);
!               if (hImcOld)
!                   pImmAssociateContext(s_hwnd, (HIMC)0);
!           }
!           active = FALSE;
        }
!       else if (hImcOld != (HIMC)0)
        {
!           pImmAssociateContext(s_hwnd, hImcOld);
!           hImcOld = (HIMC)0;
        }
! 
!       hImc = pImmGetContext(s_hwnd);
!       if (hImc)
        {
!           /*
!            * for Korean ime
!            */
!           HKL hKL = GetKeyboardLayout(0);
! 
!           if (LOWORD(hKL) == MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN))
            {
!               static DWORD dwConversionSaved = 0, dwSentenceSaved = 0;
!               static BOOL bSaved = FALSE;
! 
!               if (active)
!               {
!                   // if we have a saved conversion status, restore it
!                   if (bSaved)
!                       pImmSetConversionStatus(hImc, dwConversionSaved,
!                                                            dwSentenceSaved);
!                   bSaved = FALSE;
!               }
!               else
!               {
!                   // save conversion status and disable korean
!                   if (pImmGetConversionStatus(hImc, &dwConversionSaved,
!                                                           &dwSentenceSaved))
!                   {
!                       bSaved = TRUE;
!                       pImmSetConversionStatus(hImc,
!                               dwConversionSaved & ~(IME_CMODE_NATIVE
!                                                      | IME_CMODE_FULLSHAPE),
!                               dwSentenceSaved);
!                   }
!               }
            }
- 
-           pImmSetOpenStatus(hImc, active);
-           pImmReleaseContext(s_hwnd, hImc);
        }
      }
  }
  
  /*
--- 5845,5908 ----
      }
  # endif
  
!     if (!pImmGetContext)    // if NULL imm32.dll wasn't loaded (yet)
!       return;
! 
!     if (p_imdisable)
      {
!       if (hImcOld == (HIMC)0)
        {
!           hImcOld = pImmGetContext(s_hwnd);
!           if (hImcOld)
!               pImmAssociateContext(s_hwnd, (HIMC)0);
        }
!       active = FALSE;
!     }
!     else if (hImcOld != (HIMC)0)
!     {
!       pImmAssociateContext(s_hwnd, hImcOld);
!       hImcOld = (HIMC)0;
!     }
! 
!     hImc = pImmGetContext(s_hwnd);
!     if (!hImc)
!       return;
! 
!     /*
!      * for Korean ime
!      */
!     HKL hKL = GetKeyboardLayout(0);
! 
!     if (LOWORD(hKL) == MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN))
!     {
!       static DWORD dwConversionSaved = 0, dwSentenceSaved = 0;
!       static BOOL bSaved = FALSE;
! 
!       if (active)
        {
!           // if we have a saved conversion status, restore it
!           if (bSaved)
!               pImmSetConversionStatus(hImc, dwConversionSaved,
!                       dwSentenceSaved);
!           bSaved = FALSE;
        }
!       else
        {
!           // save conversion status and disable korean
!           if (pImmGetConversionStatus(hImc, &dwConversionSaved,
!                       &dwSentenceSaved))
            {
!               bSaved = TRUE;
!               pImmSetConversionStatus(hImc,
!                       dwConversionSaved & ~(IME_CMODE_NATIVE
!                           | IME_CMODE_FULLSHAPE),
!                       dwSentenceSaved);
            }
        }
      }
+ 
+     pImmSetOpenStatus(hImc, active);
+     pImmReleaseContext(s_hwnd, hImc);
  }
  
  /*
***************
*** 6459,6486 ****
  {
      vimmenu_T *menu = gui_find_menu(path_name);
  
!     if (menu != NULL)
!     {
!       POINT   p;
  
!       // Find the position of the current cursor
!       GetDCOrgEx(s_hdc, &p);
!       if (mouse_pos)
!       {
!           int mx, my;
  
!           gui_mch_getmouse(&mx, &my);
!           p.x += mx;
!           p.y += my;
!       }
!       else if (curwin != NULL)
!       {
!           p.x += TEXT_X(curwin->w_wincol + curwin->w_wcol + 1);
!           p.y += TEXT_Y(W_WINROW(curwin) + curwin->w_wrow + 1);
!       }
!       msg_scroll = FALSE;
!       gui_mch_show_popupmenu_at(menu, (int)p.x, (int)p.y);
      }
  }
  
  # if defined(FEAT_TEAROFF) || defined(PROTO)
--- 6460,6487 ----
  {
      vimmenu_T *menu = gui_find_menu(path_name);
  
!     if (menu == NULL)
!       return;
  
!     POINT     p;
  
!     // Find the position of the current cursor
!     GetDCOrgEx(s_hdc, &p);
!     if (mouse_pos)
!     {
!       int     mx, my;
! 
!       gui_mch_getmouse(&mx, &my);
!       p.x += mx;
!       p.y += my;
      }
+     else if (curwin != NULL)
+     {
+       p.x += TEXT_X(curwin->w_wincol + curwin->w_wcol + 1);
+       p.y += TEXT_Y(W_WINROW(curwin) + curwin->w_wrow + 1);
+     }
+     msg_scroll = FALSE;
+     gui_mch_show_popupmenu_at(menu, (int)p.x, (int)p.y);
  }
  
  # if defined(FEAT_TEAROFF) || defined(PROTO)
***************
*** 8274,8298 ****
      static void
  close_signicon_image(signicon_t *sign)
  {
!     if (sign)
!       switch (sign->uType)
!       {
!           case IMAGE_BITMAP:
!               DeleteObject((HGDIOBJ)sign->hImage);
!               break;
!           case IMAGE_CURSOR:
!               DestroyCursor((HCURSOR)sign->hImage);
!               break;
!           case IMAGE_ICON:
!               DestroyIcon((HICON)sign->hImage);
!               break;
  # ifdef FEAT_XPM_W32
!           case IMAGE_XPM:
!               DeleteObject((HBITMAP)sign->hImage);
!               DeleteObject((HBITMAP)sign->hShape);
!               break;
  # endif
!       }
  }
  
      void *
--- 8275,8301 ----
      static void
  close_signicon_image(signicon_t *sign)
  {
!     if (sign == NULL)
!       return;
! 
!     switch (sign->uType)
!     {
!       case IMAGE_BITMAP:
!           DeleteObject((HGDIOBJ)sign->hImage);
!           break;
!       case IMAGE_CURSOR:
!           DestroyCursor((HCURSOR)sign->hImage);
!           break;
!       case IMAGE_ICON:
!           DestroyIcon((HICON)sign->hImage);
!           break;
  # ifdef FEAT_XPM_W32
!       case IMAGE_XPM:
!           DeleteObject((HBITMAP)sign->hImage);
!           DeleteObject((HBITMAP)sign->hShape);
!           break;
  # endif
!     }
  }
  
      void *
***************
*** 8347,8357 ****
      void
  gui_mch_destroy_sign(void *sign)
  {
!     if (sign)
!     {
!       close_signicon_image((signicon_t *)sign);
!       vim_free(sign);
!     }
  }
  #endif
  
--- 8350,8360 ----
      void
  gui_mch_destroy_sign(void *sign)
  {
!     if (sign == NULL)
!       return;
! 
!     close_signicon_image((signicon_t *)sign);
!     vim_free(sign);
  }
  #endif
  
***************
*** 8561,8570 ****
      if (pnmh->idFrom != ID_BEVAL_TOOLTIP) // it is not our tooltip
        return;
  
!     if (cur_beval != NULL)
      {
-       switch (pnmh->code)
-       {
        case TTN_SHOW:
            break;
        case TTN_POP: // Before tooltip disappear
--- 8564,8574 ----
      if (pnmh->idFrom != ID_BEVAL_TOOLTIP) // it is not our tooltip
        return;
  
!     if (cur_beval == NULL)
!       return;
! 
!     switch (pnmh->code)
      {
        case TTN_SHOW:
            break;
        case TTN_POP: // Before tooltip disappear
***************
*** 8589,8595 ****
                info->uFlags |= TTF_DI_SETITEM;
            }
            break;
-       }
      }
  }
  
--- 8593,8598 ----
*** ../vim-9.0.1157/src/gui_x11.c       2022-09-17 21:07:52.099993159 +0100
--- src/gui_x11.c       2023-01-08 13:38:57.109602493 +0000
***************
*** 2194,2204 ****
      void
  gui_mch_set_fg_color(guicolor_T color)
  {
!     if (color != prev_fg_color)
!     {
!       XSetForeground(gui.dpy, gui.text_gc, (Pixel)color);
!       prev_fg_color = color;
!     }
  }
  
  /*
--- 2194,2204 ----
      void
  gui_mch_set_fg_color(guicolor_T color)
  {
!     if (color == prev_fg_color)
!       return;
! 
!     XSetForeground(gui.dpy, gui.text_gc, (Pixel)color);
!     prev_fg_color = color;
  }
  
  /*
***************
*** 2207,2217 ****
      void
  gui_mch_set_bg_color(guicolor_T color)
  {
!     if (color != prev_bg_color)
!     {
!       XSetBackground(gui.dpy, gui.text_gc, (Pixel)color);
!       prev_bg_color = color;
!     }
  }
  
  /*
--- 2207,2217 ----
      void
  gui_mch_set_bg_color(guicolor_T color)
  {
!     if (color == prev_bg_color)
!       return;
! 
!     XSetBackground(gui.dpy, gui.text_gc, (Pixel)color);
!     prev_bg_color = color;
  }
  
  /*
***************
*** 2814,2831 ****
      void
  gui_mch_menu_grey(vimmenu_T *menu, int grey)
  {
!     if (menu->id != (Widget)0)
!     {
!       gui_mch_menu_hidden(menu, False);
!       if (grey
  #ifdef FEAT_GUI_MOTIF
!               || !menu->sensitive
  #endif
!               )
!           XtSetSensitive(menu->id, False);
!       else
!           XtSetSensitive(menu->id, True);
!     }
  }
  
  /*
--- 2814,2831 ----
      void
  gui_mch_menu_grey(vimmenu_T *menu, int grey)
  {
!     if (menu->id == (Widget)0)
!       return;
! 
!     gui_mch_menu_hidden(menu, False);
!     if (grey
  #ifdef FEAT_GUI_MOTIF
!           || !menu->sensitive
  #endif
!        )
!       XtSetSensitive(menu->id, False);
!     else
!       XtSetSensitive(menu->id, True);
  }
  
  /*
***************
*** 2834,2846 ****
      void
  gui_mch_menu_hidden(vimmenu_T *menu, int hidden)
  {
!     if (menu->id != (Widget)0)
!     {
!       if (hidden)
!           XtUnmanageChild(menu->id);
!       else
!           XtManageChild(menu->id);
!     }
  }
  
  /*
--- 2834,2846 ----
      void
  gui_mch_menu_hidden(vimmenu_T *menu, int hidden)
  {
!     if (menu->id == (Widget)0)
!       return;
! 
!     if (hidden)
!       XtUnmanageChild(menu->id);
!     else
!       XtManageChild(menu->id);
  }
  
  /*
***************
*** 3130,3144 ****
  {
      XImage    *sign;
  
!     if (gui.in_use && (sign = (XImage *)sign_get_image(typenr)) != NULL)
!     {
!       XClearArea(gui.dpy, gui.wid, TEXT_X(col), TEXT_Y(row) - sign->height,
!               SIGN_WIDTH, gui.char_height, FALSE);
!       XPutImage(gui.dpy, gui.wid, gui.text_gc, sign, 0, 0,
!               TEXT_X(col) + (SIGN_WIDTH - sign->width) / 2,
!               TEXT_Y(row) - sign->height,
!               sign->width, sign->height);
!     }
  }
  
      void *
--- 3130,3144 ----
  {
      XImage    *sign;
  
!     if (!gui.in_use || (sign = (XImage *)sign_get_image(typenr)) == NULL)
!       return;
! 
!     XClearArea(gui.dpy, gui.wid, TEXT_X(col), TEXT_Y(row) - sign->height,
!           SIGN_WIDTH, gui.char_height, FALSE);
!     XPutImage(gui.dpy, gui.wid, gui.text_gc, sign, 0, 0,
!           TEXT_X(col) + (SIGN_WIDTH - sign->width) / 2,
!           TEXT_Y(row) - sign->height,
!           sign->width, sign->height);
  }
  
      void *
***************
*** 3202,3219 ****
  gui_mch_mousehide(
      int               hide)   // TRUE = use blank ptr, FALSE = use parent ptr
  {
!     if (gui.pointer_hidden != hide)
!     {
!       gui.pointer_hidden = hide;
!       if (hide)
!           XDefineCursor(gui.dpy, gui.wid, gui.blank_pointer);
!       else
  #ifdef FEAT_MOUSESHAPE
!           mch_set_mouse_shape(last_shape);
  #else
!           XUndefineCursor(gui.dpy, gui.wid);
  #endif
-     }
  }
  
  #if defined(FEAT_MOUSESHAPE) || defined(PROTO)
--- 3202,3219 ----
  gui_mch_mousehide(
      int               hide)   // TRUE = use blank ptr, FALSE = use parent ptr
  {
!     if (gui.pointer_hidden == hide)
!       return;
! 
!     gui.pointer_hidden = hide;
!     if (hide)
!       XDefineCursor(gui.dpy, gui.wid, gui.blank_pointer);
!     else
  #ifdef FEAT_MOUSESHAPE
!       mch_set_mouse_shape(last_shape);
  #else
!     XUndefineCursor(gui.dpy, gui.wid);
  #endif
  }
  
  #if defined(FEAT_MOUSESHAPE) || defined(PROTO)
***************
*** 3280,3301 ****
      void
  gui_mch_menu_set_tip(vimmenu_T *menu)
  {
!     if (menu->id != NULL && menu->parent != NULL
!                                      && menu_is_toolbar(menu->parent->name))
!     {
!       // Always destroy and create the balloon, in case the string was
!       // changed.
!       if (menu->tip != NULL)
!       {
!           gui_mch_destroy_beval_area(menu->tip);
!           menu->tip = NULL;
!       }
!       if (menu->strings[MENU_INDEX_TIP] != NULL)
!           menu->tip = gui_mch_create_beval_area(
!                   menu->id,
!                   menu->strings[MENU_INDEX_TIP],
!                   NULL,
!                   NULL);
!     }
  }
  #endif
--- 3280,3301 ----
      void
  gui_mch_menu_set_tip(vimmenu_T *menu)
  {
!     if (menu->id == NULL || menu->parent == NULL
!                               || !menu_is_toolbar(menu->parent->name))
!       return;
! 
!     // Always destroy and create the balloon, in case the string was
!     // changed.
!     if (menu->tip != NULL)
!     {
!       gui_mch_destroy_beval_area(menu->tip);
!       menu->tip = NULL;
!     }
!     if (menu->strings[MENU_INDEX_TIP] != NULL)
!       menu->tip = gui_mch_create_beval_area(
!               menu->id,
!               menu->strings[MENU_INDEX_TIP],
!               NULL,
!               NULL);
  }
  #endif
*** ../vim-9.0.1157/src/gui_xim.c       2022-11-24 00:08:58.465010528 +0000
--- src/gui_xim.c       2023-01-08 13:38:57.109602493 +0000
***************
*** 199,230 ****
      void
  xim_set_focus(int focus)
  {
!     if (xic != NULL)
!     {
!       if (focus)
!           gtk_im_context_focus_in(xic);
!       else
!           gtk_im_context_focus_out(xic);
!     }
  }
  
      void
  im_set_position(int row, int col)
  {
!     if (xic != NULL)
!     {
!       GdkRectangle area;
! 
!       area.x = FILL_X(col);
!       area.y = FILL_Y(row);
!       area.width  = gui.char_width * (mb_lefthalve(row, col) ? 2 : 1);
!       area.height = gui.char_height;
! 
!       gtk_im_context_set_cursor_location(xic, &area);
! 
!       if (p_imst == IM_OVER_THE_SPOT)
!           im_preedit_window_set_position();
!     }
  }
  
  #  if 0 || defined(PROTO) // apparently only used in gui_x11.c
--- 199,230 ----
      void
  xim_set_focus(int focus)
  {
!     if (xic == NULL)
!       return;
! 
!     if (focus)
!       gtk_im_context_focus_in(xic);
!     else
!       gtk_im_context_focus_out(xic);
  }
  
      void
  im_set_position(int row, int col)
  {
!     if (xic == NULL)
!       return;
! 
!     GdkRectangle area;
! 
!     area.x = FILL_X(col);
!     area.y = FILL_Y(row);
!     area.width  = gui.char_width * (mb_lefthalve(row, col) ? 2 : 1);
!     area.height = gui.char_height;
! 
!     gtk_im_context_set_cursor_location(xic, &area);
! 
!     if (p_imst == IM_OVER_THE_SPOT)
!       im_preedit_window_set_position();
  }
  
  #  if 0 || defined(PROTO) // apparently only used in gui_x11.c
*** ../vim-9.0.1157/src/version.c       2023-01-07 14:50:59.044362174 +0000
--- src/version.c       2023-01-08 13:40:52.941514804 +0000
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     1158,
  /**/

-- 
Mrs Abbott: I'm a paediatrician.
     Basil: Feet?
Mrs Abbott: Children.
     Sybil: Oh, Basil!
     Basil: Well, children have feet, don't they? That's how they move
            around, my dear. You must take a look next time, it's most
            interesting.                               (Fawlty Towers)

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20230108134501.5D0221C046A%40moolenaar.net.

Raspunde prin e-mail lui