address C1_MacroAssembler::call_c_with_frame_resize(address dest, int frame_resize) { if (frame_resize) { resize_frame(-frame_resize, R0); } #if defined(ABI_ELFv2) address return_pc = call_c(dest, relocInfo::runtime_call_type); #else address return_pc = call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, dest), relocInfo::runtime_call_type); #endif if (frame_resize) { resize_frame(frame_resize, R0); } return return_pc; }
/** @brief This function makes a window fullscreen. It resizes it, but resets the values back to their originals @return void **/ void change_frame_state (Display *display, struct Frame *frame, enum Window_state state , struct Separators *seps, const struct Workarea *workarea, struct Themes *themes, struct Atoms *atoms) { if(state == fullscreen) { int x = frame->x; int y = frame->y; int w = frame->w; int h = frame->h; //Make the window look fullscreen and then swap the variables back frame->x = 0 - themes->window_type[frame->type][window].x; frame->y = 0 - themes->window_type[frame->type][window].y; frame->w = workarea->screen_width + frame->hspace; frame->h = workarea->screen_height + frame->vspace; frame->state = none; resize_frame(display, frame, workarea, themes); frame->state = state; stack_frame(display, frame, seps); frame->x = x; frame->y = y; frame->w = w; frame->h = h; XChangeProperty(display, frame->framed_window, atoms->wm_state, XA_ATOM, 32, PropModeReplace, (unsigned char *)&atoms->wm_state_fullscreen, 1); XFlush(display); #ifdef SHOW_FRAME_STATE printf("Making window fullscreen %s\n", frame->window_name); #endif } if(state == none) { frame->state = none; //make sure that the property is removed XDeleteProperty(display, frame->framed_window, atoms->wm_state); stack_frame(display, frame, seps); resize_frame(display, frame, workarea, themes); XFlush(display); #ifdef SHOW_FRAME_STATE printf("Making window state none %s\n", frame->window_name); #endif } if(state == minimized) { frame->state = minimized; XChangeProperty(display, frame->framed_window, atoms->wm_state, XA_ATOM, 32, PropModeReplace, (unsigned char *)&atoms->wm_state_hidden, 1); XFlush(display); #ifdef SHOW_FRAME_STATE printf("Making window hidden/minimized %s\n", frame->window_name); #endif } return; }
/** @brief Recover a window chosen from the window menu or in response to a successful _NET_ACTIVE_WINDOW request @param frames workspace the frame is in @param i index of the frame in the workspaces list of frames. @return void **/ void recover_frame(Display *display, struct Workspace *frames, int i /*index*/, struct Separators *seps, const struct Workarea *workarea, struct Themes *themes) { //allow desktop windows to be recovered/tiled. Otherwise the user has no way to recover a desktop window. if(frames->list[i]->mode == desktop) { if(drop_frame(frames, i, False, workarea)) { change_frame_mode(display, frames->list[i], tiling, workarea, themes); resize_frame(display, frames->list[i], workarea, themes); } } else if(frames->list[i]->mode == tiling) { if(drop_frame(frames, i, False, workarea)) { XMapWindow(display, frames->list[i]->widgets[frame_parent].widget); frames->list[i]->state = none; } } else if(frames->list[i]->mode == floating) { if(drop_frame(frames, i, True, workarea)) { XMapWindow(display, frames->list[i]->widgets[frame_parent].widget); frames->list[i]->state = none; } } else { XMapWindow(display, frames->list[i]->widgets[frame_parent].widget); frames->list[i]->state = none; } stack_frame(display, frames->list[i], seps); reset_frame_titlebar(display, frames->list[i]); XFlush(display); }
/** @brief This function changes the frames mode to the desired mode. It shows the appropriate mode menu on the frame and resizes/moves the frame if appropriate. If the mode is "tiling" it cannot ensure that the windows do not overlap because it doesn't have access to the frame list. If the mode is set to "unset" then it sets the frame to whatever frame->mode currently is. In the create frame function, this must be after create_frame_subwindows is called. It is also after the get_frame_mode function, which sets the frame->mode directly before the create_frame_subwindows. It should then be called with the mode "unset" @return void **/ void change_frame_mode(Display *display, struct Frame *frame, enum Window_mode mode, const struct Workarea *workarea, struct Themes *themes) { /**** Set the initial frame mode to whatever frame mode currently. This is done when the frame is created. ***/ if(mode == unset) { mode = frame->mode; } /**** Undo state changes from current frame mode before settings new mode ****/ else { if(frame->mode == desktop) { frame->mode = mode; check_frame_limits(frame, workarea, themes); resize_frame(display, frame, workarea, themes); } } XFlush(display); /*** Change the state of the frame to the new mode ***/ if(mode == floating) { frame->mode = floating; change_mode_pulldown_text_pixmap(display, frame, mode_dropdown_text_floating, themes); } else if(mode == tiling) { frame->mode = tiling; change_mode_pulldown_text_pixmap(display, frame, mode_dropdown_text_tiling, themes); //cannot drop frame here because it requires access to the whole frame list check_frame_limits(frame, workarea, themes); resize_frame(display, frame, workarea, themes); } else if(mode == desktop) { change_mode_pulldown_text_pixmap(display, frame, mode_dropdown_text_desktop, themes); frame->mode = desktop; check_frame_limits(frame, workarea, themes); resize_frame(display, frame, workarea, themes); } reset_frame_titlebar(display, frame); }
void message_view::load_finished(bool ok) { if (ok) { DBG_PRINTF(5, "load_finished"); m_bodyv->set_loaded(true); if (!m_highlight_words.empty()) { m_bodyv->highlight_terms(m_highlight_words); } resize_frame(); int h = height(); resize(width(),h-1); resize(width(),h); } else { DBG_PRINTF(2, "load_finished not OK"); } }
void message_view::change_zoom(int direction) { if (direction>0) m_zoom_factor = m_zoom_factor*1.3; else if (direction<0) m_zoom_factor = m_zoom_factor/1.3; else m_zoom_factor=1.0; m_bodyv->setTextSizeMultiplier(m_zoom_factor); /* By setting a zero height, we force webkit to recompute the height instead of reusing the previous one, otherwise our outer frame's size wouldn't be adjusted */ QSize s=m_bodyv->page()->viewportSize(); s.setHeight(0); m_bodyv->page()->setViewportSize(s); resize_frame(); }
/** @brief drop frame is normally called when the mode of the frame is going to change. In that case, we can determine whether we want to try and tile it next to all tiling windows or just panels However, in several cases we are just trying to enforce whatever it's exiting tiling policy is. This function is a wrapper for drop frame that does that. @return True if the frame fits, False otherwise **/ Bool redrop_frame (Display *display, struct Workspace *frames, int clicked_frame, const struct Workarea *workarea, struct Themes *themes) { Bool result = False; if(frames->list[clicked_frame]->mode == floating) { //Floating windows only need to avoid panels result = drop_frame(frames, clicked_frame, True, workarea); } else { result = drop_frame(frames, clicked_frame, False, workarea); } // If anything has been moved or resized we need // to check it's ok and reflect the changes // in the window // These *might* make the window smaller if(result) { check_frame_limits(frames->list[clicked_frame], workarea, themes); resize_frame(display, frames->list[clicked_frame], workarea, themes); XFlush(display); } return result; }
/** @pre all parameters intitalized and allocated properly. @brief This function changes the user's workspace to the workspace at the specified index. If a negative index is passed (This is done when the currently open workspace is removed), it changes to a default workspace which is currently 0. If a negative index is passed but no workspace is open nothing happens. Generally, it is expected that at least one workspace is open. Windows from other workspaces are unmapped. @post The user's workspace has visibly changed. @return void **/ void change_to_workspace(Display *display, struct Workspace_list *workspaces, int *current_workspace, struct Workspace **frames, int index, struct Separators *seps, const struct Workarea *workarea, struct Themes *themes, struct Atoms *atoms) { struct Workspace *workspace = &workspaces->list[*current_workspace]; if(*current_workspace != -1) *frames = workspace; struct Saved_frame_state *frame_state; if(workspaces->used_workspaces == 0) { *frames = NULL; *current_workspace = -1; return; //don't do anything if no windows are open } if(*current_workspace < workspaces->used_workspaces /*this function is sometimes called to change from an invalid workspace that has been closed */ && *current_workspace >= 0) { for(int i = 0; i < workspace->used; i++) { //So we can figure out where to save the frame state we need to calculate the pointer offset. int real_frame_index = get_offset_in_array(workspace->list[i], workspaces->frame_list, sizeof(struct Frame)); if(workspace->list[i]->sticky == False) { XUnmapWindow(display, workspace->list[i]->widgets[frame_parent].widget); XUnmapWindow(display, workspace->list[i]->menu.item); } //printf("real_frame_index %d, i = %d, current_workspace %d\n", real_frame_index, i, *current_workspace); frame_state = &workspace->states[real_frame_index]; frame_state->need_to_tile = 0; save_frame_state(frame_state, workspace->list[i]); } free(workspace->list); workspace->list = NULL; workspace->used = 0; } XSync(display, False); //if index is -1, change to default workspace which is 0 if(index < 0 && workspaces->used_workspaces > 0) index = 0; *current_workspace = index; workspace = &workspaces->list[*current_workspace]; *frames = workspace; workspace->max = DEFAULT_STARTING_FRAMES; workspace->list = malloc(sizeof(struct Frames *) * workspace->max ); if(!workspace->list) { perror("Couldn't allocate frame list"); return; } //Do all the panels because we want them to be tiled first. for(int i = 0; i < workspaces->used_frames; i++) { if(workspaces->frame_list[i].sticky == True) { if(ensure_empty_frame_reference_slots(workspace) == False) { perror("Couldn't allocate frame list"); return; } int ref_index = workspace->used; struct Frame *frame = workspace->list[ref_index] = &workspaces->frame_list[i]; if(drop_frame(workspace, ref_index, False, workarea)) { //this should be easy as they should already be non-overlapping change_frame_mode(display, frame, tiling, workarea, themes); } else { change_frame_state(display, frame, minimized, seps, workarea, themes, atoms); fprintf(stderr, "Couldn't tile panel! It is called %s\n", frame->window_name); } resize_frame(display, frame, workarea, themes); stack_frame(display, frame, seps); XMapWindow(display, frame->widgets[frame_parent].widget); //Actually only needs to be mapped the first time but doesn't matter workspace->used++; } } for(int i = 0; i < workspaces->used_frames; i++) { frame_state = &workspace->states[i]; if(frame_state->available != 0 && frame_state->sticky == False) { if(ensure_empty_frame_reference_slots(workspace) == False) { perror("Couldn't allocate frame list"); return; } int ref_index = workspace->used; struct Frame *frame = workspace->list[ref_index] = &workspaces->frame_list[i]; load_frame_state(display, frame_state, frame, seps, workarea, themes, atoms); if(workspace->states[i].need_to_tile) { if(drop_frame(workspace, ref_index, False, workarea)) { //this should be easy as they should already be non-overlapping change_frame_mode(display, frame, tiling, workarea, themes); } else { change_frame_state(display, frame, minimized, seps, workarea, themes, atoms); //TODO set urgency hint } workspace->states[i].need_to_tile = 0; } else if(frame->mode == floating) { if(!drop_frame(workspace, ref_index, True, workarea)) { change_frame_state(display, frame, minimized, seps, workarea, themes, atoms); //TODO set urgency hint } } resize_frame(display, frame, workarea, themes); stack_frame(display, frame, seps); if(frame->state != minimized) XMapWindow(display, frame->widgets[frame_parent].widget); XMapWindow(display, workspace->list[ref_index]->menu.item); workspace->used++; } } update_client_list(display, workspace, atoms); // printf("changing focus to one in new workspace\n"); recover_focus(display, workspace, atoms); XFlush(display); }
/** @brief Reparents the specified framed_window to a newly created frame. @return returns 1 if successful or 0 if no window was created. @todo A the moment each pointer is totally valid, in the future it will merely be an alias from another datastructure. **/ int create_frame(Display *display, struct Frame* frame , Window framed_window, struct Popup_menu *window_menu, struct Separators *seps, const struct Workarea *workarea, struct Themes *themes , struct Cursors *cursors, struct Atoms *atoms) { XWindowAttributes get_attributes; //printf("Creating frames->list[%d] with window %lu, connection %lu\n" //, frames->used, (unsigned long)framed_window, (unsigned long)display); //add this window to the save set as soon as possible so that if an error occurs it is still available XAddToSaveSet(display, framed_window); XSync(display, False); XGetWindowAttributes(display, framed_window, &get_attributes); /*** Set up defaults ***/ frame->focussed = False; frame->sticky = False; frame->window_name = NULL; frame->framed_window = framed_window; frame->type = unknown; frame->theme_type = unknown; frame->mode = unset; frame->state = none; frame->wants_attention = False; frame->transient = 0; frame->width_inc = 1; frame->height_inc = 1; frame->menu.item = 0; frame->w_inc_offset = 0; frame->h_inc_offset = 0; frame->w = get_attributes.width; frame->h = get_attributes.height; get_frame_type_and_mode (display, frame, atoms, themes); frame->x = get_attributes.x - themes->window_type[frame->theme_type][window].x; frame->y = get_attributes.y - themes->window_type[frame->theme_type][window].y; frame->hspace = 0 - themes->window_type[frame->theme_type][window].w; frame->vspace = 0 - themes->window_type[frame->theme_type][window].h; // This is not set to the something sensive, like the size of the workarea // as it may change and we can't tell if it's a default value or a real // one set by the client. // Instead, always use the MIN of the workarea dimension and these values frame->max_width = INT_MAX; frame->max_height = INT_MAX; //prevent overly small windows with these sensible defaults frame->min_width = MINWIDTH + frame->hspace; frame->min_height = MINHEIGHT + frame->vspace; #ifdef ALLOW_OVERSIZE_WINDOWS_WITHOUT_MINIMUM_HINTS Screen* screen = DefaultScreenOfDisplay(display); /* Ugh Horrible. */ /* Many apps that are resizeable ask to be the size of the screen and since windows often don't specifiy their minimum size, we have no other way of knowing if they really need to be that size or not. In case they do, this specifies that their current width is their minimum size, in the hope that it is overridden by the size hints. This kind of behaviour causes problems on small screens like the eee pc. */ if(frame->w > XWidthOfScreen(screen)) frame->min_width = frame->w; if(frame->h > XHeightOfScreen(screen)) frame->min_height = frame->h; #endif /* This requires hspace and vspace to be set as well as the incremental hints */ get_frame_hints(display, frame); frame_type_settings(display, frame, workarea); //Don't manage splash screens, they just cause the workspace to be created and instantly destroyed if(frame->type == splash) { XMapWindow(display, framed_window); XFlush(display); return 0; } get_frame_state(display, frame, atoms); create_frame_subwindows(display, frame, workarea, themes, cursors); create_frame_name(display, window_menu, frame, themes, atoms); get_frame_wm_hints(display, frame); //this might need to change the focus, it's mode (to hidden) and so on get_frame_strut_hints_as_normal_hints(display, frame, atoms); //_NET_FRAME_EXTENTS, left, right, top, bottom, CARDINAL[4]/32 int32_t ewmh_frame_extents[4] = { themes->window_type[frame->theme_type][window].x , themes->window_type[frame->theme_type][window].y , - themes->window_type[frame->theme_type][window].x - themes->window_type[frame->theme_type][window].w , - themes->window_type[frame->theme_type][window].y - themes->window_type[frame->theme_type][window].h }; XChangeProperty(display, framed_window, atoms->frame_extents, XA_CARDINAL , 32, PropModeReplace, (unsigned char *)ewmh_frame_extents, 4); XSetWindowBorderWidth(display, framed_window, 0); change_frame_mode(display, frame, unset, workarea, themes); #ifdef CRASH_ON_BUG XGrabServer(display); XSetErrorHandler(supress_xerror); #endif XSelectInput(display, framed_window, 0); //reparent the framed_window to frame->widgets[window].widget XReparentWindow(display, framed_window, frame->widgets[window].widget, 0, 0); //for some odd reason the reparent only reports an extra unmap event if the window was already unmapped XRaiseWindow(display, framed_window); XMapWindow(display, frame->widgets[window].widget); #ifdef CRASH_ON_BUG XSetErrorHandler(NULL); XUngrabServer(display); #endif XSelectInput(display, framed_window, PropertyChangeMask); //Property notify is used to update titles XSelectInput(display, frame->widgets[window].widget , SubstructureRedirectMask | SubstructureNotifyMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask); //Some windows only send the destroy event (e.g., gimp splash screen) XSync(display, False); //Intercept clicks so we can set the focus and possibly raise floating windows XGrabButton(display, Button1, 0, frame->widgets[window].widget , False, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None); //do it for numlock as well XGrabButton(display, Button1, Mod2Mask, frame->widgets[window].widget , False, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None); frame->w += frame->hspace; frame->h += frame->vspace; check_frame_limits(frame, workarea, themes); resize_frame(display, frame, workarea, themes); stack_frame(display, frame, seps); change_frame_state(display, frame, frame->state, seps, workarea, themes, atoms); XMoveResizeWindow(display, framed_window, 0, 0, frame->w - frame->hspace, frame->h - frame->vspace); XMoveWindow(display, framed_window, 0, 0); XMapWindow(display, framed_window); XFlush(display); save_frame_initial_state(frame); return 1; }