/[rdesktop]/sourceforge.net/branches/seamlessrdp-branch/rdesktop/xwin.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/branches/seamlessrdp-branch/rdesktop/xwin.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1143 by ossman_, Thu Mar 16 08:41:53 2006 UTC revision 1170 by astrand, Mon Mar 20 15:43:15 2006 UTC
# Line 54  typedef struct _seamless_window Line 54  typedef struct _seamless_window
54  {  {
55          Window wnd;          Window wnd;
56          unsigned long id;          unsigned long id;
57          unsigned long parent;          unsigned long behind;
         XWMHints *hints;  
58          int xoffset, yoffset;          int xoffset, yoffset;
59          int width, height;          int width, height;
60          int state;              /* normal/minimized/maximized. */          int state;              /* normal/minimized/maximized. */
61          unsigned int desktop;          unsigned int desktop;
62            struct timeval *position_timer;
63    
64            BOOL outstanding_position;
65            unsigned int outpos_serial;
66            int outpos_xoffset, outpos_yoffset;
67            int outpos_width, outpos_height;
68    
69          struct _seamless_window *next;          struct _seamless_window *next;
70  } seamless_window;  } seamless_window;
71  static seamless_window *g_seamless_windows = NULL;  static seamless_window *g_seamless_windows = NULL;
72    static unsigned long g_seamless_focused = 0;
73    static BOOL g_seamless_started = False; /* Server end is up and running */
74    static BOOL g_seamless_active = False;  /* We are currently in seamless mode */
75  extern BOOL g_seamless_rdp;  extern BOOL g_seamless_rdp;
76    
77  extern uint32 g_embed_wnd;  extern uint32 g_embed_wnd;
# Line 261  static int rop2_map[] = { Line 270  static int rop2_map[] = {
270  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, GXcopy); }  #define RESET_FUNCTION(rop2)    { if (rop2 != ROP2_COPY) XSetFunction(g_display, g_gc, GXcopy); }
271    
272  static seamless_window *  static seamless_window *
273  seamless_get_window_by_id(unsigned long id)  sw_get_window_by_id(unsigned long id)
274  {  {
275          seamless_window *sw;          seamless_window *sw;
276          for (sw = g_seamless_windows; sw; sw = sw->next)          for (sw = g_seamless_windows; sw; sw = sw->next)
# Line 274  seamless_get_window_by_id(unsigned long Line 283  seamless_get_window_by_id(unsigned long
283    
284    
285  static seamless_window *  static seamless_window *
286  seamless_get_window_by_wnd(Window wnd)  sw_get_window_by_wnd(Window wnd)
287  {  {
288          seamless_window *sw;          seamless_window *sw;
289          for (sw = g_seamless_windows; sw; sw = sw->next)          for (sw = g_seamless_windows; sw; sw = sw->next)
# Line 287  seamless_get_window_by_wnd(Window wnd) Line 296  seamless_get_window_by_wnd(Window wnd)
296    
297    
298  static void  static void
299  seamless_remove_window(seamless_window * win)  sw_remove_window(seamless_window * win)
300  {  {
301          seamless_window *sw, **prevnext = &g_seamless_windows;          seamless_window *sw, **prevnext = &g_seamless_windows;
302          for (sw = g_seamless_windows; sw; sw = sw->next)          for (sw = g_seamless_windows; sw; sw = sw->next)
# Line 295  seamless_remove_window(seamless_window * Line 304  seamless_remove_window(seamless_window *
304                  if (sw == win)                  if (sw == win)
305                  {                  {
306                          *prevnext = sw->next;                          *prevnext = sw->next;
                         XFree(sw->hints);  
307                          xfree(sw);                          xfree(sw);
308                          return;                          return;
309                  }                  }
# Line 307  seamless_remove_window(seamless_window * Line 315  seamless_remove_window(seamless_window *
315    
316  /* Move all windows except wnd to new desktop */  /* Move all windows except wnd to new desktop */
317  static void  static void
318  seamless_all_to_desktop(Window wnd, unsigned int desktop)  sw_all_to_desktop(Window wnd, unsigned int desktop)
319  {  {
320          seamless_window *sw;          seamless_window *sw;
321          for (sw = g_seamless_windows; sw; sw = sw->next)          for (sw = g_seamless_windows; sw; sw = sw->next)
# Line 323  seamless_all_to_desktop(Window wnd, unsi Line 331  seamless_all_to_desktop(Window wnd, unsi
331  }  }
332    
333    
334    /* Send our position */
335    static void
336    sw_update_position(seamless_window * sw)
337    {
338            XWindowAttributes wa;
339            int x, y;
340            Window child_return;
341            unsigned int serial;
342    
343            XGetWindowAttributes(g_display, sw->wnd, &wa);
344            XTranslateCoordinates(g_display, sw->wnd, wa.root,
345                                  -wa.border_width, -wa.border_width, &x, &y, &child_return);
346    
347            serial = seamless_send_position(sw->id, x, y, wa.width, wa.height, 0);
348    
349            sw->outstanding_position = True;
350            sw->outpos_serial = serial;
351    
352            sw->outpos_xoffset = x;
353            sw->outpos_yoffset = y;
354            sw->outpos_width = wa.width;
355            sw->outpos_height = wa.height;
356    }
357    
358    
359    /* Check if it's time to send our position */
360    static void
361    sw_check_timers()
362    {
363            seamless_window *sw;
364            struct timeval now;
365    
366            gettimeofday(&now, NULL);
367            for (sw = g_seamless_windows; sw; sw = sw->next)
368            {
369                    if (timerisset(sw->position_timer) && timercmp(sw->position_timer, &now, <))
370                    {
371                            timerclear(sw->position_timer);
372                            sw_update_position(sw);
373                    }
374            }
375    }
376    
377    
378    static void
379    sw_restack_window(seamless_window * sw, unsigned long behind)
380    {
381            seamless_window *sw_above;
382    
383            /* Remove window from stack */
384            for (sw_above = g_seamless_windows; sw_above; sw_above = sw_above->next)
385            {
386                    if (sw_above->behind == sw->id)
387                            break;
388            }
389    
390            if (sw_above)
391                    sw_above->behind = sw->behind;
392    
393            /* And then add it at the new position */
394    
395            for (sw_above = g_seamless_windows; sw_above; sw_above = sw_above->next)
396            {
397                    if (sw_above->behind == behind)
398                            break;
399            }
400    
401            if (sw_above)
402                    sw_above->behind = sw->id;
403    
404            sw->behind = behind;
405    }
406    
407    
408    static void
409    sw_handle_restack(seamless_window * sw)
410    {
411            Status status;
412            Window root, parent, *children;
413            unsigned int nchildren, i;
414            seamless_window *sw_below;
415    
416            status = XQueryTree(g_display, RootWindowOfScreen(g_screen),
417                                &root, &parent, &children, &nchildren);
418            if (!status || !nchildren)
419                    return;
420    
421            sw_below = NULL;
422    
423            i = 0;
424            while (children[i] != sw->wnd)
425            {
426                    i++;
427                    if (i >= nchildren)
428                            return;
429            }
430    
431            for (i++; i < nchildren; i++)
432            {
433                    sw_below = sw_get_window_by_wnd(children[i]);
434                    if (sw_below)
435                            break;
436            }
437    
438            if (!sw_below && !sw->behind)
439                    return;
440            if (sw_below && (sw_below->id == sw->behind))
441                    return;
442    
443            if (sw_below)
444            {
445                    seamless_send_zchange(sw->id, sw_below->id, 0);
446                    sw_restack_window(sw, sw_below->id);
447            }
448            else
449            {
450                    seamless_send_zchange(sw->id, 0, 0);
451                    sw_restack_window(sw, 0);
452            }
453    }
454    
455    
456  static void  static void
457  mwm_hide_decorations(Window wnd)  mwm_hide_decorations(Window wnd)
458  {  {
# Line 1567  ui_create_window(void) Line 1697  ui_create_window(void)
1697          }          }
1698    
1699          XSelectInput(g_display, g_wnd, input_mask);          XSelectInput(g_display, g_wnd, input_mask);
1700          if (!g_seamless_rdp)  
1701            XMapWindow(g_display, g_wnd);
1702            /* wait for VisibilityNotify */
1703            do
1704          {          {
1705                  XMapWindow(g_display, g_wnd);                  XMaskEvent(g_display, VisibilityChangeMask, &xevent);
                 /* wait for VisibilityNotify */  
                 do  
                 {  
                         XMaskEvent(g_display, VisibilityChangeMask, &xevent);  
                 }  
                 while (xevent.type != VisibilityNotify);  
                 g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;  
1706          }          }
1707            while (xevent.type != VisibilityNotify);
1708            g_Unobscured = xevent.xvisibility.state == VisibilityUnobscured;
1709    
1710          g_focused = False;          g_focused = False;
1711          g_mouse_in_wnd = False;          g_mouse_in_wnd = False;
# Line 1641  xwin_toggle_fullscreen(void) Line 1769  xwin_toggle_fullscreen(void)
1769  {  {
1770          Pixmap contents = 0;          Pixmap contents = 0;
1771    
1772          if (g_seamless_rdp)          if (g_seamless_active)
1773                  /* Turn off SeamlessRDP mode */                  /* Turn off SeamlessRDP mode */
1774                  ui_seamless_toggle();                  ui_seamless_toggle();
1775    
# Line 1746  handle_button_event(XEvent xevent, BOOL Line 1874  handle_button_event(XEvent xevent, BOOL
1874          }          }
1875  }  }
1876    
1877    
1878  /* Process events in Xlib queue  /* Process events in Xlib queue
1879     Returns 0 after user quit, 1 otherwise */     Returns 0 after user quit, 1 otherwise */
1880  static int  static int
# Line 1878  xwin_process_events(void) Line 2007  xwin_process_events(void)
2007                                  if (g_grab_keyboard && g_mouse_in_wnd)                                  if (g_grab_keyboard && g_mouse_in_wnd)
2008                                          XGrabKeyboard(g_display, g_wnd, True,                                          XGrabKeyboard(g_display, g_wnd, True,
2009                                                        GrabModeAsync, GrabModeAsync, CurrentTime);                                                        GrabModeAsync, GrabModeAsync, CurrentTime);
2010    
2011                                    sw = sw_get_window_by_wnd(xevent.xfocus.window);
2012                                    if (!sw)
2013                                            break;
2014    
2015                                    if (sw->id != g_seamless_focused)
2016                                    {
2017                                            seamless_send_focus(sw->id, 0);
2018                                            g_seamless_focused = sw->id;
2019                                    }
2020                                  break;                                  break;
2021    
2022                          case FocusOut:                          case FocusOut:
# Line 1920  xwin_process_events(void) Line 2059  xwin_process_events(void)
2059                                  }                                  }
2060                                  else                                  else
2061                                  {                                  {
2062                                          sw = seamless_get_window_by_wnd(xevent.xexpose.window);                                          sw = sw_get_window_by_wnd(xevent.xexpose.window);
2063                                          if (sw)                                          if (sw)
2064                                                  XCopyArea(g_display, g_backstore,                                                  XCopyArea(g_display, g_backstore,
2065                                                            xevent.xexpose.window, g_gc,                                                            xevent.xexpose.window, g_gc,
# Line 1970  xwin_process_events(void) Line 2109  xwin_process_events(void)
2109                                          break;                                          break;
2110    
2111                                  /* seamless */                                  /* seamless */
2112                                  sw = seamless_get_window_by_wnd(xevent.xproperty.window);                                  sw = sw_get_window_by_wnd(xevent.xproperty.window);
2113                                  if (!sw)                                  if (!sw)
2114                                          break;                                          break;
2115    
# Line 1985  xwin_process_events(void) Line 2124  xwin_process_events(void)
2124                                      && (xevent.xproperty.state == PropertyNewValue))                                      && (xevent.xproperty.state == PropertyNewValue))
2125                                  {                                  {
2126                                          sw->desktop = ewmh_get_window_desktop(sw->wnd);                                          sw->desktop = ewmh_get_window_desktop(sw->wnd);
2127                                          seamless_all_to_desktop(sw->wnd, sw->desktop);                                          sw_all_to_desktop(sw->wnd, sw->desktop);
2128                                  }                                  }
2129    
2130                                  break;                                  break;
2131                          case MapNotify:                          case MapNotify:
2132                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2133                                          rdp_send_client_window_status(1);                                          rdp_send_client_window_status(1);
2134                                  break;                                  break;
2135                          case UnmapNotify:                          case UnmapNotify:
2136                                  if (!g_seamless_rdp)                                  if (!g_seamless_active)
2137                                          rdp_send_client_window_status(0);                                          rdp_send_client_window_status(0);
2138                                  break;                                  break;
2139                            case ConfigureNotify:
2140                                    if (!g_seamless_active)
2141                                            break;
2142    
2143                                    sw = sw_get_window_by_wnd(xevent.xconfigure.window);
2144                                    if (!sw)
2145                                    {
2146                                            error("ConfigureNotify for unknown window 0x%lx\n",
2147                                                  xevent.xconfigure.window);
2148                                    }
2149    
2150                                    gettimeofday(sw->position_timer, NULL);
2151                                    if (sw->position_timer->tv_usec + SEAMLESSRDP_POSITION_TIMER >=
2152                                        1000000)
2153                                    {
2154                                            sw->position_timer->tv_usec +=
2155                                                    SEAMLESSRDP_POSITION_TIMER - 1000000;
2156                                            sw->position_timer->tv_sec += 1;
2157                                    }
2158                                    else
2159                                    {
2160                                            sw->position_timer->tv_usec += SEAMLESSRDP_POSITION_TIMER;
2161                                    }
2162    
2163                                    sw_handle_restack(sw);
2164                                    break;
2165                  }                  }
2166          }          }
2167          /* Keep going */          /* Keep going */
# Line 2020  ui_select(int rdp_socket) Line 2185  ui_select(int rdp_socket)
2185                          /* User quit */                          /* User quit */
2186                          return 0;                          return 0;
2187    
2188                    if (g_seamless_active)
2189                            sw_check_timers();
2190    
2191                  FD_ZERO(&rfds);                  FD_ZERO(&rfds);
2192                  FD_ZERO(&wfds);                  FD_ZERO(&wfds);
2193                  FD_SET(rdp_socket, &rfds);                  FD_SET(rdp_socket, &rfds);
# Line 2039  ui_select(int rdp_socket) Line 2207  ui_select(int rdp_socket)
2207    
2208                  /* add redirection handles */                  /* add redirection handles */
2209                  rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);                  rdpdr_add_fds(&n, &rfds, &wfds, &tv, &s_timeout);
2210                    seamless_select_timeout(&tv);
2211    
2212                  n++;                  n++;
2213    
# Line 3007  ui_end_update(void) Line 3176  ui_end_update(void)
3176  {  {
3177  }  }
3178    
3179    
3180    void
3181    ui_seamless_begin()
3182    {
3183            if (!g_seamless_rdp)
3184                    return;
3185    
3186            if (g_seamless_started)
3187                    return;
3188    
3189            g_seamless_started = True;
3190            ui_seamless_toggle();
3191    }
3192    
3193    
3194  void  void
3195  ui_seamless_toggle()  ui_seamless_toggle()
3196  {  {
3197          if (g_seamless_rdp)          if (!g_seamless_rdp)
3198                    return;
3199    
3200            if (!g_seamless_started)
3201                    return;
3202    
3203            if (g_seamless_active)
3204          {          {
3205                  /* Deactivate */                  /* Deactivate */
3206                  while (g_seamless_windows)                  while (g_seamless_windows)
3207                  {                  {
3208                          XDestroyWindow(g_display, g_seamless_windows->wnd);                          XDestroyWindow(g_display, g_seamless_windows->wnd);
3209                          seamless_remove_window(g_seamless_windows);                          sw_remove_window(g_seamless_windows);
3210                  }                  }
3211                  XMapWindow(g_display, g_wnd);                  XMapWindow(g_display, g_wnd);
3212          }          }
3213          else          else
3214          {          {
3215                  /* Activate */                  /* Activate */
                 if (g_win_button_size)  
                 {  
                         error("SeamlessRDP mode cannot be activated when using single application mode\n");  
                         return;  
                 }  
                 if (!g_using_full_workarea)  
                 {  
                         error("SeamlessRDP mode requires a session that covers the whole screen");  
                         return;  
                 }  
   
3216                  XUnmapWindow(g_display, g_wnd);                  XUnmapWindow(g_display, g_wnd);
3217                  seamless_send_sync();                  seamless_send_sync();
3218          }          }
3219    
3220          g_seamless_rdp = !g_seamless_rdp;          g_seamless_active = !g_seamless_active;
3221  }  }
3222    
3223    
3224  void  void
3225  ui_seamless_create_window(unsigned long id, unsigned long parent, unsigned long flags)  ui_seamless_create_window(unsigned long id, unsigned long parent, unsigned long flags)
3226  {  {
# Line 3051  ui_seamless_create_window(unsigned long Line 3231  ui_seamless_create_window(unsigned long
3231          long input_mask;          long input_mask;
3232          seamless_window *sw, *sw_parent;          seamless_window *sw, *sw_parent;
3233    
3234            if (!g_seamless_active)
3235                    return;
3236    
3237          /* Ignore CREATEs for existing windows */          /* Ignore CREATEs for existing windows */
3238          sw = seamless_get_window_by_id(id);          sw = sw_get_window_by_id(id);
3239          if (sw)          if (sw)
3240                  return;                  return;
3241    
# Line 3087  ui_seamless_create_window(unsigned long Line 3270  ui_seamless_create_window(unsigned long
3270                  XFree(sizehints);                  XFree(sizehints);
3271          }          }
3272    
3273            /* Handle popups without parents through some ewm hints */
3274            if (parent == 0xFFFFFFFF)
3275                    ewmh_set_window_popup(wnd);
3276          /* Set WM_TRANSIENT_FOR, if necessary */          /* Set WM_TRANSIENT_FOR, if necessary */
3277          if ((parent != 0x00000000) && (parent != 0xFFFFFFFF))          else if (parent != 0x00000000)
3278          {          {
3279                  sw_parent = seamless_get_window_by_id(parent);                  sw_parent = sw_get_window_by_id(parent);
3280                  if (sw_parent)                  if (sw_parent)
3281                          XSetTransientForHint(g_display, wnd, sw_parent->wnd);                          XSetTransientForHint(g_display, wnd, sw_parent->wnd);
3282                  else                  else
# Line 3110  ui_seamless_create_window(unsigned long Line 3296  ui_seamless_create_window(unsigned long
3296             serverside, instead of terminating rdesktop */             serverside, instead of terminating rdesktop */
3297          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);          XSetWMProtocols(g_display, wnd, &g_kill_atom, 1);
3298    
3299          sw = malloc(sizeof(seamless_window));          sw = xmalloc(sizeof(seamless_window));
3300          sw->wnd = wnd;          sw->wnd = wnd;
3301          sw->id = id;          sw->id = id;
3302          sw->parent = parent;          sw->behind = 0;
         sw->hints = XAllocWMHints();  
         sw->hints->flags = 0;  
3303          sw->xoffset = 0;          sw->xoffset = 0;
3304          sw->yoffset = 0;          sw->yoffset = 0;
3305          sw->width = 0;          sw->width = 0;
3306          sw->height = 0;          sw->height = 0;
3307          sw->state = SEAMLESSRDP_NOTYETMAPPED;          sw->state = SEAMLESSRDP_NOTYETMAPPED;
3308          sw->desktop = 0;          sw->desktop = 0;
3309            sw->position_timer = xmalloc(sizeof(struct timeval));
3310            timerclear(sw->position_timer);
3311            sw->outstanding_position = False;
3312          sw->next = g_seamless_windows;          sw->next = g_seamless_windows;
3313          g_seamless_windows = sw;          g_seamless_windows = sw;
3314  }  }
# Line 3132  ui_seamless_destroy_window(unsigned long Line 3319  ui_seamless_destroy_window(unsigned long
3319  {  {
3320          seamless_window *sw;          seamless_window *sw;
3321    
3322          sw = seamless_get_window_by_id(id);          if (!g_seamless_active)
3323                    return;
3324    
3325            sw = sw_get_window_by_id(id);
3326          if (!sw)          if (!sw)
3327          {          {
3328                  warning("ui_seamless_destroy_window: No information for window 0x%lx\n", id);                  warning("ui_seamless_destroy_window: No information for window 0x%lx\n", id);
# Line 3140  ui_seamless_destroy_window(unsigned long Line 3330  ui_seamless_destroy_window(unsigned long
3330          }          }
3331    
3332          XDestroyWindow(g_display, sw->wnd);          XDestroyWindow(g_display, sw->wnd);
3333          seamless_remove_window(sw);          sw_remove_window(sw);
3334  }  }
3335    
3336    
# Line 3149  ui_seamless_move_window(unsigned long id Line 3339  ui_seamless_move_window(unsigned long id
3339  {  {
3340          seamless_window *sw;          seamless_window *sw;
3341    
3342          sw = seamless_get_window_by_id(id);          if (!g_seamless_active)
3343                    return;
3344    
3345            sw = sw_get_window_by_id(id);
3346          if (!sw)          if (!sw)
3347          {          {
3348                  warning("ui_seamless_move_window: No information for window 0x%lx\n", id);                  warning("ui_seamless_move_window: No information for window 0x%lx\n", id);
3349                  return;                  return;
3350          }          }
3351    
3352            /* We ignore server updates until it has handled our request. */
3353            if (sw->outstanding_position)
3354                    return;
3355    
3356          if (!width || !height)          if (!width || !height)
3357                  /* X11 windows must be at least 1x1 */                  /* X11 windows must be at least 1x1 */
3358                  return;                  return;
3359    
3360          /* About MAX and MIN: Windows allows moving a window outside          sw->xoffset = x;
3361             the desktop. This happens, for example, when maximizing an          sw->yoffset = y;
3362             application. In this case, the position is set to something          sw->width = width;
3363             like -4,-4,1288,1032. Many WMs does not allow windows          sw->height = height;
            outside the desktop, however. Therefore, clip the window  
            ourselves. */  
         sw->xoffset = MAX(0, x);  
         sw->yoffset = MAX(0, y);  
         sw->width = MIN(MIN(width, width + x), g_width - sw->xoffset);  
         sw->height = MIN(MIN(height, height + y), g_height - sw->yoffset);  
3364    
3365          /* If we move the window in a maximized state, then KDE won't          /* If we move the window in a maximized state, then KDE won't
3366             accept restoration */             accept restoration */
# Line 3186  ui_seamless_move_window(unsigned long id Line 3377  ui_seamless_move_window(unsigned long id
3377    
3378    
3379  void  void
3380    ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long flags)
3381    {
3382            seamless_window *sw;
3383    
3384            if (!g_seamless_active)
3385                    return;
3386    
3387            sw = sw_get_window_by_id(id);
3388            if (!sw)
3389            {
3390                    warning("ui_seamless_restack_window: No information for window 0x%lx\n", id);
3391                    return;
3392            }
3393    
3394            if (behind)
3395            {
3396                    seamless_window *sw_behind;
3397                    Window wnds[2];
3398    
3399                    sw_behind = sw_get_window_by_id(behind);
3400                    if (!sw_behind)
3401                    {
3402                            warning("ui_seamless_restack_window: No information for window 0x%lx\n",
3403                                    behind);
3404                            return;
3405                    }
3406    
3407                    wnds[1] = sw_behind->wnd;
3408                    wnds[0] = sw->wnd;
3409    
3410                    XRestackWindows(g_display, wnds, 2);
3411            }
3412            else
3413            {
3414                    XRaiseWindow(g_display, sw->wnd);
3415            }
3416    
3417            sw_restack_window(sw, behind);
3418    }
3419    
3420    
3421    void
3422  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)  ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags)
3423  {  {
3424          seamless_window *sw;          seamless_window *sw;
3425    
3426          sw = seamless_get_window_by_id(id);          if (!g_seamless_active)
3427                    return;
3428    
3429            sw = sw_get_window_by_id(id);
3430          if (!sw)          if (!sw)
3431          {          {
3432                  warning("ui_seamless_settitle: No information for window 0x%lx\n", id);                  warning("ui_seamless_settitle: No information for window 0x%lx\n", id);
# Line 3208  ui_seamless_setstate(unsigned long id, u Line 3444  ui_seamless_setstate(unsigned long id, u
3444  {  {
3445          seamless_window *sw;          seamless_window *sw;
3446    
3447          sw = seamless_get_window_by_id(id);          if (!g_seamless_active)
3448                    return;
3449    
3450            sw = sw_get_window_by_id(id);
3451          if (!sw)          if (!sw)
3452          {          {
3453                  warning("ui_seamless_setstate: No information for window 0x%lx\n", id);                  warning("ui_seamless_setstate: No information for window 0x%lx\n", id);
# Line 3230  ui_seamless_setstate(unsigned long id, u Line 3469  ui_seamless_setstate(unsigned long id, u
3469                             XIconifyWindow is easier. */                             XIconifyWindow is easier. */
3470                          if (sw->state == SEAMLESSRDP_NOTYETMAPPED)                          if (sw->state == SEAMLESSRDP_NOTYETMAPPED)
3471                          {                          {
3472                                  sw->hints->flags |= StateHint;                                  XWMHints *hints;
3473                                  sw->hints->initial_state = IconicState;                                  hints = XAllocWMHints();
3474                                  XSetWMHints(g_display, sw->wnd, sw->hints);                                  hints->flags = StateHint;
3475                                    hints->initial_state = IconicState;
3476                                    XSetWMHints(g_display, sw->wnd, hints);
3477                                    XFree(hints);
3478                                  XMapWindow(g_display, sw->wnd);                                  XMapWindow(g_display, sw->wnd);
3479                          }                          }
3480                          else                          else
# Line 3243  ui_seamless_setstate(unsigned long id, u Line 3485  ui_seamless_setstate(unsigned long id, u
3485                          break;                          break;
3486          }          }
3487    
         /* Handle popups without parents through some ewm hints */  
         if ((sw->state == SEAMLESSRDP_NOTYETMAPPED) && (sw->parent == 0xFFFFFFFF))  
                 ewmh_set_window_popup(sw->wnd);  
   
3488          sw->state = state;          sw->state = state;
3489  }  }
3490    
# Line 3254  ui_seamless_setstate(unsigned long id, u Line 3492  ui_seamless_setstate(unsigned long id, u
3492  void  void
3493  ui_seamless_syncbegin(unsigned long flags)  ui_seamless_syncbegin(unsigned long flags)
3494  {  {
3495            if (!g_seamless_active)
3496                    return;
3497    
3498          /* Destroy all seamless windows */          /* Destroy all seamless windows */
3499          while (g_seamless_windows)          while (g_seamless_windows)
3500          {          {
3501                  XDestroyWindow(g_display, g_seamless_windows->wnd);                  XDestroyWindow(g_display, g_seamless_windows->wnd);
3502                  seamless_remove_window(g_seamless_windows);                  sw_remove_window(g_seamless_windows);
3503          }          }
3504  }  }
3505    
3506    
3507    void
3508    ui_seamless_ack(unsigned int serial)
3509    {
3510            seamless_window *sw;
3511            for (sw = g_seamless_windows; sw; sw = sw->next)
3512            {
3513                    if (sw->outpos_serial == serial)
3514                    {
3515                            sw->xoffset = sw->outpos_xoffset;
3516                            sw->yoffset = sw->outpos_yoffset;
3517                            sw->width = sw->outpos_width;
3518                            sw->height = sw->outpos_height;
3519                            sw->outstanding_position = False;
3520                            break;
3521                    }
3522            }
3523    
3524            return;
3525    }

Legend:
Removed from v.1143  
changed lines
  Added in v.1170

  ViewVC Help
Powered by ViewVC 1.1.26