After some researches, I could at least get ride of the dirty gray bar at the top of the screen by subclassing the window's content view and add the following code to the setFrame method, before call super:
//isFullscreen
if(([self.window styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask)
{
frameRect.size.height = self.window.frame.size.height;
frameRect.size.width = self.window.frame.size.width;
}
The window get resized to the screen size before setFrame get called, so we can use its size to update frameRect to window's size.